あなたがButton
のClick
ハンドラで同期コードを実行した場合、このコードはDispatcher
スレッドで実行し、これTextBlock
にあなたのメッセージの変更を表示するなどの他のコードを実行しているからDispatcher
を防止しています。
この問題を解決するには、少なくとも3つの方法があります。
まず、あなたは別のThread
、Task
またはasync
イベントハンドラでは、あなたのExecute
コードを実行し、Dispatcher
を使用してText
を設定することができます。
private async void btn_execute_Click(object sender, RoutedEventArgs e)
{
for (int i = 0; i < 100; i++)
{
// Simulate doing some stuff...
await Task.Delay(100);
// Thanks to async/await the current context is captured and
// switches automatically back to the Dispatcher thread after the await.
output_log.Text += i + ", ";
// If you were using Task.Run() instead then you would have to invoke it manually.
// Dispatcher.Invoke(() => output_log.Text += i + ", ");
}
}
主な利点は、あなたがDispatcher
をブロックしていないということです - あなたがしているすべてのことに強くお勧めします。
第二が、あなたはDispatcher
であなたのExecute
コードをやり続けることができますが、その後、あなたはそれがすべての待機中のUIを処理できるように、あなたのテキストを更新するたびに、「フラッシュ」Dispatcher
持っています行動:
private void btn_execute_Click(object sender, RoutedEventArgs e)
{
for (int i = 0; i < 100; i++)
{
// Simulate doing some stuff...
Thread.Sleep(100);
output_log.Text += i + ", ";
Dispatcher.Invoke(DispatcherPriority.Background, new Action(() => { }));
}
}
これは確かに可能ですが、私は本当にそれをお勧めしません。
またはサード、
あなたのアーキテクチャ用
MVVM
を使用することができます
- 、
- は、
async
イベントハンドラ(またはCommand
)にごExecute
コードを実行
- 変更のみ
LogText
ViewModel
の属性と
- データバインディングを使用して
TextBlock.Text
をこのMyLogViewModel.LogText
プロパティにバインドします。
残念ながら、私はあなたに、このシナリオのための迅速なサンプルコードを与えることはできませんが、MVVM
は、WPFアプリケーションの任意の種類のために本当に自然なアーキテクチャであるため、それは確かにそれについて考える価値があります。
なぜこのコードの背後にあるのですか?MVVMを使用していませんか? – Keith