WPF のコントロールへのクロススレッド アクセスを実現する方法
WPF では、スレッド間でコントロールにアクセスするには Dispatcher オブジェクトを使います。Dispatcher オブジェクトはスレッドに関連付けられたオブジェクトで、操作を正しいスレッドに送信するためのメカニズムを提供します。
マルチスレッド間でコントロールにアクセスする一般的な方法を以下に示します。
- コントロールにアクセスする必要のあるスレッドで、そのコントロールのDispatcherオブジェクトを取得します。Application.Current.Dispatcherを使用して、現在のアプリケーションのDispatcherオブジェクトを取得できます。
- 処理をコントロールのあるスレッドに送るには、Dispatcher.InvokeメソッドまたはDispatcher.BeginInvokeメソッドを使用します。Dispatcher.Invokeは同期なので、処理が完了するまで現在のスレッドをブロックします。Dispatcher.BeginInvokeは非同期なので、現在のスレッドをブロックしません。
次の例は、バックグラウンドスレッドで UI コントロールを更新する方法を示しています。
// 在后台线程中更新UI控件的方法
private void UpdateUI()
{
// 获取UI线程的Dispatcher对象
Dispatcher uiDispatcher = Application.Current.Dispatcher;
// 在UI线程上执行操作
uiDispatcher.Invoke(() =>
{
// 在这里可以访问和更新UI控件
myTextBox.Text = "Hello, world!";
});
}
Invoke または BeginInvoke を呼び出すときに、ラムダ式を使用するか、委任を作成して実行する操作を指定できます。
UIスレッド上で実行する処理が長時間を要すると、UIの応答が低下するため、Dispatcher経由で別のスレッドからコントロールにアクセスする場合には、UIスレッド上で実行する処理が長時間を要しないように注意が必要です。時間のかかる処理は、バックグラウンドスレッドで実行し、処理完了後に、Dispatcherを使用して、UIコントロールの状態を更新するようにします。