向ThreadPool中的ObservableCollection添加项目

本文关键字:添加 项目 ObservableCollection 中的 ThreadPool | 更新日期: 2023-09-27 18:05:32

我的问题很简单,我有一个包含类型为ObservableCollection<T>的(私有)对象的类,现在我想运行一些线程(按顺序,因此ThreadPool而不是BackgroundWorkers),将新项目添加到ObservableCollection<T>

如果ObservableCollection<T>将是,让我们说,一个ProgressBar,一切都很容易(->调用),但我不知道如何调用ObservableCollection<T>对象。

我的目标是有一个类似BackgroundWorker的东西,可以运行序列。

提前感谢。

向ThreadPool中的ObservableCollection添加项目

我建议使用Task对象进行后台操作,并使用TaskScheduler.FromCurrentSynchronizationContext对UI线程进行排队更新。

假设你想添加一个StatusItem项到一个可观察对象集合。在用户控件的.cs文件中,您可以这样声明它:

ObservableCollection<StatusItem> _listStatus = 
       new ObservableCollection<StatusItem>();

然后可以声明一个方法来添加项,如下所示:

private void AddStatus(StatusItem item, bool useDispatcher)
{
    if (useDispatcher) {
        Dispatcher.BeginInvoke(DispatcherPriority.Send, 
           new ThreadStart(() => AddStatus(item, false)));
        return;
    }
    if (_listStatus.Count > MaxItemsToHoldInList) {
        // maybe you have a more efficient way to do this
        for (int i = 0; i < BlockOfItems; i++ ) _listStatus.RemoveAt(0);
    }
    _listStatus.Add(item);
    if (_scrollIntoView) listStatus.ScrollIntoView(item);
}

我有一些自由,所以也许你不需要所有这些。基本上,如果您想从工作线程内部调用此方法,则必须使用分派器将修改推迟到它到达用户线程(这听起来像是您想要做的)。您可能已经发现,如果您没有使用分派器线程,那么您的更新就不会进入GUI。当然,如果您活跃在用户线程中(例如响应鼠标点击),您可以在调用此方法时设置useDispatcher = false

我个人经常使用可观察集合来反馈给用户,因此,在我的例子中,我限制了用户能够看到的窗口。每次删除一个包中的项是为了提高性能,因为您确实需要发送那些状态消息。我还检查用户是否将拇指放在显示这些项目的列表控件的底部。如果是,那么我将_scrollIntoView设置为true,以保持最底部的项目在视图中

可以这样安全地同步对集合的访问:

lock (myCollection) {
    myCollection.InsertItem(0, myItem);
}

一次只有一个线程可以修改集合。请确保将使用集合的代码放在锁块内部。

如果不创建自己的集合类,就无法真正做到这一点。如何通过工作线程更新ObservableCollection ?

有一些线程安全的可观察对象集合的实现:http://www.deanchalk.me.uk/post/Thread-Safe-Dispatcher-Safe-Observable-Collection-for-WPF.aspx