c# - ObservableCollection 和线程

标签 c# wpf multithreading observablecollection

<分区>

我的类(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);
}

关于c# - ObservableCollection 和线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2293246/

相关文章:

c# - .WPF 应用程序生成 <appname>.dll.config 而不是 <appname>.exe.config

c# - 在复杂/单窗口 WPF 应用程序中使用 Thread 的最佳方式

swift - CloudKit 错误处理 - 重试逻辑

c# - 附属属性(property)。如何在 PropertyChangedCallback 中使用 SetValue

JavaFX 终止后台任务

c# - 内插字符串的软编码格式说明符 c# 6.0

c# - 为什么在调用 C# DLL 时不需要提供字符串缓冲区?

javascript - AngularJS - 从 .NET Controller 生成 View 只执行一次

c# - 当我使用 Entity Framework 和 CodeFirst 方法将父实体的值设置为 null 时,如何从数据库中删除相关的子实体?

c# - 如何设置 WPF 应用程序的默认字体?