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コレクションに行を追加します。

別のスレッドから呼び出された場合、例外が発生します。「このタイプのCollectionViewは、Dispatcherスレッドとは異なるスレッドからのSourceCollectionへの変更をサポートしていません。」

問題は、ISynchronizeInvokeがwpfで機能しないように見えることです。mainWindowをISynchronizeInvokeに変換できないというコンパイラエラーメッセージが表示されます。

ISynchronizeInvokeを使用する場合target=mainWindow as ISynchronizeInvoke; コンパイルできますが、ターゲットはnullです。

4

2 に答える 2

1

mainWindow.Dispatcher.Invokeにキャストしようとする代わりに、を使用できますISynchronizeInvokeDispatcher.Invokeは、WPFの正しいマーシャリングを提供します。

.NET 4.5では、BindingOperations.EnableCollectionSynchronizationを設定することにより、WPFがこれを自動的に処理する機能が追加されていることに注意してください。

于 2012-07-30T16:09:27.957 に答える
0

多くのThreadSafeObservableCollection実装のいくつかをチェックする必要があります。これらは、バックグラウンドスレッドからObservableCollectionを更新する問題を非常にうまくまとめます!

于 2012-07-30T16:06:15.570 に答える