2013-02-13 81 views
3

我一直在處理多線程問題一段時間了。在過去的幾天裏,我一直在努力確保我所有的電話都是線程安全的。我剛剛遇到了一個拋出我的問題。這裏是場景:WPF元素綁定到observablecollection更新工作線程

我試圖繪製一個波形,使用Infragistics XamDataChart控制,這是傳遞〜500點/秒/波形。在應用程序啓動時,我創建了一個名爲WaveData的ObservableCollection屬性的對象,這些屬性直接綁定到一個項目控件中的xaml。當數據進入時,它存儲在隊列中,並且派生工作者線程用於將數據出列並在適當的位置更新集合。

菌種工作者線程:

QueueProcessThread = Task.Factory.StartNew(() => UpdateWaveFormCollections(WaveForms), tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default); 

代碼來更新它運行在一個循環中集(一些代碼行略去了):

waveForm.LastDisplayedTimeStamp = DateTime.Now; // move the last displayed time up 

int collectionSize = waveForm.WaveData.Count; 
while (waveForm.WaveDataBuffer.Count > 0 && waveForm.WaveDataBuffer.Peek().TimeStamp < waveForm.LastDisplayedTimeStamp) 
{ 
    if (waveForm.CurrentPosition >= collectionSize) 
    { 
     waveForm.CurrentPosition = 0; 
    } 
    waveForm.WaveData[waveForm.CurrentPosition] = waveForm.WaveDataBuffer.Dequeue(); 
    waveForm.CurrentPosition++; 
} 

正如你所看到的,我不實際上向收藏夾中添加/刪除項目,而只是在特定位置更新項目。這是因爲我想讓它看起來像醫院裏的病人監護儀。

我遇到的問題是我意識到我在非UI線程上更新此集合,並且該集合直接綁定到Infragistics LineSeries ... 並且這是工作的。但是,當我在預期的非UI線程上更新該集合時,使用Infragistics StepLineSeries的另一個圖形將引發異常。 如何能夠更新非UI線程上的綁定集合?我對此感到擔憂,因爲1)偶爾我會得到一個錯誤,指出無法在非UI線程上更新集合,並且2)當我通過調度程序將波形更新切換到UI線程時,性能非常糟糕GUI無法使用。我需要理解爲什麼這個工作,所以我知道如何進行。由於線程管理不當,我不想部署任何可能會失敗的應用程序。我正在尋找可能的原因爲什麼/如何更新非UI線程上綁定的ObservableCollection。任何幫助/建議,將不勝感激。

回答

1

嘗試使用調度程序調用以確保集合將通過UI線程訪問,因此不允許任何其他事件在非UI線程上觸發。

Application.Current.Dispatcher.BeginInvoke(new Action(()=> 
{ 
// code here to access collection 
})); 
3

也許你需要看看使用分派器(除非你的代碼部分被省略)。

當您執行需要在UI線程上執行代碼的操作時,可以使用Dispatcher方法。

也許你可以檢索在後臺工作線程的數據,當您更新您的收藏更改傳播回UI線程

例如

Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, 
    new Action(() => methodHere = 50)); 
+0

其實這正是我所做的「防止」線程問題。但是,當性能如此糟糕時,界面無響應。此外,代碼的功能是不使用分派器,我需要知道它爲什麼工作。 – mdutra 2013-02-13 14:27:37

0

我一直在尋找的答案是,你可以但更新數據綁定對象的屬性和WPF將採取調度爲你的照顧,你不能更新的集合從非(添加/刪除/清除) UI線程。在我的波形中,我沒有添加點數,而是更新了特定索引處項目的值。但是,在另一種情況下,我總是添加和刪除點。

相關問題