C# 从线程池向ObservableCollection添加项
我的问题很简单,我有一个类,它包含一个类型为C# 从线程池向ObservableCollection添加项,c#,multithreading,C#,Multithreading,我的问题很简单,我有一个类,它包含一个类型为observedcollection的(私有)对象,现在我想运行一些线程(按顺序,因此是ThreadPool而不是BackgroundWorkers),它们向observedcollection添加新项 如果observedcollection将是一个ProgressBar,那么一切都将非常简单(->调用),但我不知道如何调用observedcollection对象 我的目标是有一个类似于BackgroundWorker的东西,可以按顺序运行 提前谢谢
observedcollection
的(私有)对象,现在我想运行一些线程(按顺序,因此是ThreadPool
而不是BackgroundWorkers
),它们向observedcollection
添加新项
如果observedcollection
将是一个ProgressBar
,那么一切都将非常简单(->调用),但我不知道如何调用observedcollection
对象
我的目标是有一个类似于BackgroundWorker
的东西,可以按顺序运行
提前谢谢。我建议使用
任务
对象进行后台操作,并使用任务调度程序将更新排队到UI线程。从CurrentSynchronizationContext可以像这样安全地同步对集合的访问:
lock (myCollection) {
myCollection.InsertItem(0, myItem);
}
ObservableCollection<StatusItem> _listStatus =
new ObservableCollection<StatusItem>();
一次只能有一个线程修改集合。确保将使用集合的任何代码放置在锁块内部。如果不创建自己的集合类,就无法真正做到这一点
有一些线程安全的observable集合的实现可用:假设您想向observable集合添加StatusItem项。在用户控件的.cs文件中,可以这样声明它:
lock (myCollection) {
myCollection.InsertItem(0, myItem);
}
ObservableCollection<StatusItem> _listStatus =
new ObservableCollection<StatusItem>();
ObservableCollection\u listStatus=
新的可观察集合();
然后,您可以声明一个方法来添加项,如下所示:
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);
}
private void AddStatus(StatusItem项,bool usedpatcher)
{
如果(使用调度程序){
Dispatcher.BeginInvoke(DispatcherPriority.Send,
新的ThreadStart(()=>AddStatus(item,false));
返回;
}
如果(_listStatus.Count>MaxItemsToHoldInList){
//也许你有更有效的方法来做这件事
对于(inti=0;i
我有一些自由,所以也许你不需要这些。基本上,如果要从工作线程内部调用此方法,则必须使用dispatcher将修改推迟到到达用户线程(这听起来像是您想要做的)。您可能已经发现,如果不使用dispatcher线程,您的更新就无法进入GUI。当然,如果您在用户线程中处于活动状态(例如,响应鼠标单击),则可以在调用此方法时设置usedpatcher=false
我个人经常使用可观察的集合来反馈给用户,因此,在我的例子中,我限制了用户能够看到的窗口。一次删除一个包中的项目是为了提高性能,而您实际上是在清除这些状态消息。我还检查用户是否将拇指放在显示这些项目的列表控件的底部。如果是这样,那么我将\u scrollIntoView
设置为true,以保持最底层的项处于视图中。是的,我已经查看了那些线程安全的可观察集合,但是存在一些问题(无论是使用还是实现),如果其他所有方法都失败,我将更努力地尝试其中一个。现在这非常有趣,晚饭后我会试试。是的,很简单,但老实说,@Stephen Cleary的解决方案看起来更符合时代,在WPF和WinForms中都能很好地工作。是的,我正在看它。无论如何谢谢你!我看了一下,但这描述了如何并行使用任务,如何“动态”生成新任务(即每次单击按钮)并将其放入队列?task.Factory.StartNew
创建新任务。请记住,这涉及两个任务:一个执行后台操作,另一个执行对ObservableCollection
的实际更新;只有“更新”任务才应使用任务调度程序
。