3

这是对这个问题的跟进。

我必须从不同的线程更新 ObservableCollection。我尝试使用以下代码:

            Thread t = new Thread(  ()=>
         {
             while(true)
             {

                 if (ErrorDetection.ErrorDetectionIO.doErrorDetection() == 1)
                 {
                     dataLine = ErrorDetection.ErrorDetectionIO.getDataLine();

                     if (mainWindow != null)
                     {
                         ISynchronizeInvoke target = mainWindow; // mainWindow needs to be an WindowsForm?
                         target.Invoke(
                            (Action)(() =>
                             {
                                mainWindow.setNewDataLine(dataLine);
                             }
                             ), null);
                     }

                 }
             }

         }  );

         t.IsBackground = true;
         t.Start();

ErrorDetectionIO.doErrorDetection() 位于 c++/cli .dll 中并调用本机 c 代码。

setNewDataLine 在 mainWindow 上,并在 Observable 集合中添加了一个 Line。

如果从不同的线程调用它会导致异常:“这种类型的 CollectionView 不支持从与 Dispatcher 线程不同的线程对其 SourceCollection 的更改。”

问题是 ISynchronize Invoke 似乎不适用于 wpf?Threres 编译器错误消息 mainWindow 无法转换为 ISynchronizeInvoke。

如果我使用 ISynchronizeInvoke target = mainWindow 作为 ISynchronizeInvoke; 它可以编译但目标为空;

4

2 回答 2

1

您可以只使用mainWindow.Dispatcher.Invoke而不是尝试强制转换为ISynchronizeInvoke. Dispatcher.Invoke将为 WPF 提供正确的封送处理。

请注意,.NET 4.5 通过设置BindingOperations.EnableCollectionSynchronization添加了 WPF 自动处理此问题的能力。

于 2012-07-30T16:09:27.957 回答
0

您应该查看许多ThreadSafeObservableCollection实现中的一些。这些将很好地解决从后台线程更新 ObservableCollection 的问题!

于 2012-07-30T16:06:15.570 回答