ObservableCollection和线程

我在课堂上有一个ObservableCollection 。 进一步进入我的课,我有一个线程。 从这个线程我想添加到我的ObservableCollection 。 但我不能这样做:

这种types的CollectionView不支持从与分派器线程不同的线程对其SourceCollection的更改。

请注意,这不是从UI线程发生的,所以我没有访问调度程序。

JaredPar的方法是有效的。 另一种值得考虑的方法是使用线程安全的ObservableCollection而不是内置的ObservableCollection 。 这里有一些实现,但在我看来, Sasha Barber的实现和CLinq Continuous Collection类是一些更好的实现。 在内部,这些类基本上使用JaredPar概述的方法,但将其封装在集合类中。

解决这个问题的最好方法是将Dispatcher对象传递给后台线程的start方法。

 void DoBackgroundOperation(ObservableCollection<SomeType> col) { var dispatcher = Dispatcher.CurrentDispatcher; ThreadStart start = () => BackgroundStart(dispatcher, col); var t = new Thread(start); t.Start(); } private static void BackgroundStart( Dispatcher dispatcher, ObservableCollection<SomeType> col) { ... SomeType t = GetSomeTypeObject(); Action del = () => col.Add(t); dispatcher.Invoke(del); } 

现在,当您需要添加到集合中时,您可以使用UI Dispatcher对象。

正如@Reed指出的那样,通过使用SynchronizationContext可以获得更一般的解决scheme。 这是一个使用SynchronizationContext创build一个委托负责添加新值的function样式示例。 这具有隐藏集合和线程模型与创build对象的代码的优点。

 void DoBackgroundOperation(ObservableCollection<SomeType> col) { var context = SynchronizationContext.Current; Action<SomeType> addFunc = (SomeType st) => context.Send(() => col.Add(st), null); ThreadStart start = () => BackgroundStart(addFunc); var t = new Thread(start); t.Start(); } private static void BackgroundStart(Action<SomeType> addFunc) { ... SomeType t = GetSomeTypeObject(); addFunc(t); } 

在In.Net 4.5中,您可以使用线程安全集合,ConcurrentDictionary,ConcurrentBag等,以适合您的需求: http : //msdn.microsoft.com/en-us/library/dd997305.aspx

请考虑阅读: http : //www.codeproject.com/Articles/208361/Concurrent-Observable-Collection-Dictionary-and-So