我的类(class)有一个ObservableCollection
。在我的类里面,我有一个话题。从这个线程我想添加到我的 ObservableCollection
。但我不能这样做:
This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread.
请注意,这不是从 UI 线程发生的,所以我无权访问调度程序。
解决这个问题最好的方法是将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
实现的。下面是使用 SynchronizationContext
创建负责添加新值的委托(delegate)的功能样式示例。这具有从创建对象的代码中隐藏集合和线程模型的优点。
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);
}