はい、できます。
Dispatcher
がTreeViewItem
を選択できるように、UIスレッドをブロックしないでください。
最も良い方法は、おそらくasync/await
をイベントハンドラで使用することです。あなたは(私はお勧めの高いと思われる)データバインディングと、その後のチャンスをMVVMを使用している場合
private async void Treeview1_OnSelectedItemChanged(object sender,
RoutedPropertyChangedEventArgs<object> e)
{
// TreeViewItem gets selected immediately.
// Now let's do some background work, for example getting some data.
await Task.Run(() => DoSomeBackgroundWork());
// And fill the DataGrid with the results.
// Thanks to async/await we're already in the dispatcher thread again.
dataGrid.Items.Add(...);
}
private void DoSomeBackgroundWork()
{
// Simulate some blocking synchronous work.
Thread.Sleep(1000);
}
:あなたはMVVMを使用し、直接あなたのUI要素を操作する必要がない場合
は、あなたはこのような何かを行うことができますディスパッチャスレッドでViewModel
の内容を入力する必要はありません。
代わりに、あなたはasync
コンテキストでそれを行うだけディスパッチャスレッドへのコンテキストスイッチが後で必要とされない上からawait
を伝えることができます:
await Task.Run(() => DoSomeBackgroundWork())
.ConfigureAwait(continueOnCapturedContext: false);
myViewModel.Items.Add(...);
しかし、あなたが最も可能性の高いいくつかのフォームを適用する必要があることに注意してくださいユーザーが複数のTreeViewItems
をすばやくクリックすると、複数のTask.Run()
が相互に干渉しないという保証はないため、並行性の安全性についても同様です。
(フィールドまたはプロパティに格納された単純な揮発性フラグから始まる)並行性の安全性を確保するには多くの方法がありますが、この1つの答えにすべてを含めるにはあまりにも多くの方法があります。
たとえば、Stephen Clearyを確認できます。彼はこのテーマについていくつかのすばらしい記事を書いています。
Stephen Toub .NETでの非同期プログラミングの実装に密接に関連しています。
一般的なアドバイスとして、できるだけディスパッチャスレッド内で少しでも行うようにしてください。 UI要素を直接変更するなど、絶対に必要とするアクションのみを実行してください。
UIスレッドを 'Thread.Sleep()'でブロックしないでください。あなたは何を達成しようとしていますか? – dymanoid
私はしばらく時間がかかるデータでDataGridを埋めようとしています。現在、私はTreeViewアイテムをクリックしたように非常に遅い感じがします。その後、DataGridを塗りつぶしてTreeViewアイテムを選択します。 –