System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
我正在添加/删除不在UI线程上的ObservableCollection。
我有一个名为EnqueueReport的方法要添加到集合中,还有一个DequeueReport要从集合中删除。
步骤流程如下:
- 1.call EnqueueReport每当请求新报告时
1.每隔几秒钟调用一个方法来检查是否生成了报告(它有一个foreach循环,用于检查ObservableCollection中所有报告的生成状态)
1.如果生成报告,则调用DequeueReport
我对C#库不太了解,有人能指导我吗?
6条答案
按热度按时间yzuktlbb1#
从.net framwork 4. 5开始,您可以使用本机集合同步。
BindingOperations.EnableCollectionSynchronization(YourCollection, YourLockObject);
YourLockObject
是任何对象的执行严修,例如new Object();
。每个集合使用一个。这就消除了一些特殊类或任何东西的需要。只是启用和享受;)
[edit]*正如Mark和Ed在评论中所说的那样(感谢澄清!),这 * 并 * 不能减轻您在更新时锁定集合的负担,因为它只是同步集合-视图-绑定, 并 * 不能神奇地使集合本身成为线程安全的。[/edit]**
PS:
BindingOperations
位于命名空间System.Windows.Data
中。i7uq4tfw2#
Franck在这里发布的解决方案适用于一个线程添加内容的情况,但ObservableCollection本身(以及它所基于的List)不是线程安全的。如果多个线程正在向集合写入,则可能会引入难以跟踪的bug。我编写了一个ObservableCollection版本,它使用ReaderWriteLockSlim来实现真正的线程安全。
Unfortunately, it hit the StackOverflow character limit, so here it is on PasteBin.对于多个读取器/写入器,这应该可以100%正常工作。就像常规的ObservableCollection一样,在回调中修改集合是无效的(在接收回调的线程上)。
06odsfpq3#
你可以创建一个简单的线程友好版本的可观察集合。如下所示:
有了它,现在做一个大规模的查找和替换,并改变你所有的
ObservableCollection
到MTObservableCollection
和你的好去lg40wkob4#
您可以使用ObservableConcurrentCollection类。它们位于Microsoft提供的并行扩展附加程序库中的一个包中。
您可以在Nuget上获得社区预先构建的版本:https://www.nuget.org/packages/ParallelExtensionsExtras/
或从Microsoft的以下站点获取:
https://code.msdn.microsoft.com/ParExtSamples
f5emj3cl5#
本文是为Xamarin.Forms用户编写的,但它也适用于需要使ObservableCollections线程安全的任何人:
https://codetraveler.io/2019/09/11/using-observablecollection-in-a-multi-threaded-xamarin-forms-application/
这是一个非常短的解决方案。
初始化集合后,添加以下内容:
并将此方法添加到同一个类中:
作者是布兰登·明尼克。
44u64gxh6#