0

這是我的問題,我創建了一個SortableCollection:ObservableCollection 並添加了一個排序方法(排序顏色)。 當我排序與主要線程的集合,它的作品的每一件事情都很好,並且工作 但是當我嘗試通過使用集合中的項目來排序此customCollection時,我有一個期望:(調用線程無法訪問此對象,因爲不同的線程擁有它)。 我看了網頁,我發現了幾種解決方案,One Solution如何創建一個observableCollection可排序和多線程

這種類型的解決方案把收集多線程插入,刪除移動操作。 但不適用於自定義排序。 感謝您的幫助,

回答

0

WPF類具有線程關聯性。這意味着對這些對象的所有更改必須位於創建它們的同一個線程中。創建一個線程安全的用戶界面API確實很難,所以微軟選擇保持它的單線程並強制運行時檢查以確保它。

也就是說,有幾個選項需要在後臺線程中執行排序,然後將其應用於UI線程中。第一個選項是將您的SortableCollection複製到一個普通的舊List或Array中,並在後臺執行排序。一旦後臺線程完成,您就可以使用Dispatcher在UI線程中執行代碼。 WPF中的每個UI元素都延伸System.Windows.Threading.DispatcherObject,大部分延伸System.Windows.Freezable。 DispatcherObject是讓Dispatcher在UI線程中執行代碼的地方。

從邏輯上講,執行將是這樣的:

public void BackgroundSort() 
{ 
    List<T> items = new List<T>(this.ToArray()); 
    BackgroundSortDelegate del = Sort; 

    del.BeginInvoke(SortCompleted, del); 
} 

private void SortCompleted(IAsyncResult result) 
{ 
    BackgroundSortDelegate del = result.AsyncState as BackgroundSortDelegate; 

    List<T> items = del.EndInvoke(result); 
    this.Dispatcher.Invoke(()=>{this.Collection = items;}); 
} 

所發生的短的解釋是,後臺工作/委託在此列表中使用項目的副本。排序完成後,我們調用Dispatcher對象並調用一個操作。在這個動作中,我們將新的排序列表分配給我們的對象。

在UI線程內分配任何後臺工作結果的關鍵是使用UI的Dispatcher對象。實際上可能有六種方法在C#中調用後臺工作程序,但將後臺線程放到UI線程中的方法是相同的。

+0

感謝Berin的解釋, 但是,我必須把這種方法? 在SortableCollection中或者在處理排序方法的事件處理程序中? – Khaldoun 2010-12-21 14:21:05

+0

無論它對你來說最合理的邏輯。在SortableCollection中做這件事的好處是你可以將SortableCollection傳遞給不同的方法,並且它們可以自動與它進行交互。請注意警告:調度程序是一項昂貴的操作。偶爾可以調用它,但是在一個緊密的循環中它會減慢速度。 – 2010-12-21 14:38:47