如何使 ObservableCollection 线程安全? [英] How to make ObservableCollection thread-safe?
问题描述
System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
我正在添加/删除不在 UI 线程上的 ObservableCollection.
I am adding/removing from an ObservableCollection which is not on a UI thread.
我有一个名为 EnqueueReport 的方法可以添加到集合中,还有一个 DequeueReport 可以从集合中移除.
I have a method names EnqueueReport to add to the colleciton and a DequeueReport to remove from the colleciton.
步骤流程如下:-
- 1. 每当请求新报告时调用 EnqueueReport
- 每隔几秒调用一个方法来检查报告是否生成(这有一个 foreach 循环,用于检查 ObservableCollection 中所有报告的生成状态)
- 如果生成报告,则调用 DequeueReport
我对 C# 库的了解不多.有人可以指导我吗?
I am not much in C# libraries. Can someone please guide me on this?
推荐答案
您可以创建可观察集合的简单线程友好版本.像下面这样:
You can create a simple thread friendly version of the observable collection. Like the following :
public class MTObservableCollection<T> : ObservableCollection<T>
{
public override event NotifyCollectionChangedEventHandler CollectionChanged;
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
NotifyCollectionChangedEventHandler CollectionChanged = this.CollectionChanged;
if (CollectionChanged != null)
foreach (NotifyCollectionChangedEventHandler nh in CollectionChanged.GetInvocationList())
{
DispatcherObject dispObj = nh.Target as DispatcherObject;
if (dispObj != null)
{
Dispatcher dispatcher = dispObj.Dispatcher;
if (dispatcher != null && !dispatcher.CheckAccess())
{
dispatcher.BeginInvoke(
(Action)(() => nh.Invoke(this,
new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset))),
DispatcherPriority.DataBind);
continue;
}
}
nh.Invoke(this, e);
}
}
}
现在做一个大规模的发现 &将您所有的 ObservableCollection
替换并更改为 MTObservableCollection
并祝您好运
with that now do a massive find & replace and change all your ObservableCollection
to MTObservableCollection
and your good to go
这篇关于如何使 ObservableCollection 线程安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!