【问题标题】:switching to dispatcher thread in WPF在 WPF 中切换到调度程序线程
【发布时间】:2012-07-30 16:03:32
【问题描述】:

这是Question的后续行动。

我必须从不同的线程更新 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?出现编译器错误消息,提示 mainWindow 无法转换为 ISynchronizeInvoke。

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

【问题讨论】:

    标签: c# wpf multithreading


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-02-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多