0

これは私の問題です。私はSortableCollectionを作成しました:ObservableCollection を追加し、並べ替えメソッド(色の並べ替え)を追加しました。 プリンシパルスレッドでコレクションを並べ替えると、すべて正常に動作していて動作します しかし、このcustomCollectionをコレクション内のアイテムを使用してソートしようとすると、私はexpetionを持っています。(呼び出しスレッドは、別のスレッドがそれを所有している)。 私はウェブを見て、いくつかの解決策を見つけました。One SolutionobservableCollectionを作成する方法

このタイプのソリューションは、マルチスレッドを挿入して移動操作を削除しました。 しかし、カスタムソートではありません。 ヘルプのおかげで、

答えて

0

WPFクラスにはスレッド親和性があります。つまり、これらのオブジェクトへのすべての変更は、作成された同じスレッド内になければなりません。スレッドセーフであるユーザーインターフェイスAPIを作成することは本当に難しいため、マイクロソフトではスレッドをシングルスレッドにして、実行時のチェックを強制してそのことを確認しました。

つまり、バックグラウンドスレッドでソートを実行してUIスレッドで適用する必要があるというオプションがいくつかあります。最初のオプションは、SortableCollectionを普通の古いリストまたは配列にコピーし、バックグラウンドでソートを実行することです。バックグラウンドスレッドが完了したら、Dispatcherを使用してUIスレッドでコードを実行します。 WPFのすべてのUI要素はSystem.Windows.Threading.DispatcherObjectを拡張し、ほとんどの要素はSystem.Windows.Freezableです。 DispatcherObjectは、UIスレッドでコードを実行するDispatcherを取得する場所です。

論理的には、実行はこのようなものになるだろう:

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

説明ありがとうございました、 しかし、私はこのメソッドを置く必要がありますか? SortableCollection、またはソートメソッドを宣言するイベントハンドラでは? – Khaldoun

+0

あなたが論理的に最も理にかなっているところはどこにでもあります。 SortableCollectionでそれを行う利点は、SortableCollectionだけをさまざまなメソッドに渡すことができ、自動的にそのメソッドとやり取りできることです。警告の注記:Dispatcherは高価な操作です。それはときどき呼び出されても問題ありませんが、タイトなループでは実際には遅くなります。 –

関連する問題