WPFでクロススレッドでコントロールにアクセスする方法
WPF でコントロールにクロススレッドでアクセスする主な方法は次のとおりです。
- Dispatcherオブジェクトを使用します。コントロールのスレッドコンテキスト外からコントロールにアクセスする必要がったときは、コントロールのDispatcherオブジェクトを使用してコントロールにアクセスします。DispatcherオブジェクトはInvokeメソッドやBeginInvokeメソッドを提供し、必要な操作をデリゲートにラップしてUIスレッドのメッセージキューに追加し、UIスレッドコンテキストで実行させます。
翻訳本は、翻訳家によって訳されたものです。
// 在非UI线程中访问控件
Application.Current.Dispatcher.Invoke(() =>
{
// 执行需要访问控件的操作
});
- SynchronizationContextオブジェクトを使用:UIスレッドのSynchronizationContextオブジェクトを取得することで、UIスレッドコンテキストで実行できるように、実行する必要がある操作をSendまたはPostメソッド内のデリゲートとしてカプセル化して送信できます。
そうすれば、ツールを使用せずに、ネイティブな方法でアクセントを付けることができます。
// 获取UI线程的SynchronizationContext对象
SynchronizationContext uiContext = SynchronizationContext.Current;
// 在非UI线程中访问控件
uiContext.Send(state =>
{
// 执行需要访问控件的操作
}, null);
- Async/Await を使う: 非同期メソッド内で、await キーワードを用いて、UI スレッドのコンテキストでの操作が完了するのを待ってから、それ以降のコードを実行することができます。
ネイティブにしか伝わらない、日本語で言い換えた文章を1つだけ考えてください。
// 异步方法中访问控件
await Application.Current.Dispatcher.InvokeAsync(() =>
{
// 执行需要访问控件的操作
});
クロススレッドでコントロールにアクセスする際は、コントロールのプロパティやメソッドに直接アクセスせず、上記のメソッドを利用してコントロール操作を行う必要があります。これにより、操作がUIスレッドのコンテキストで実行されて、スレッドアクセスエラーやUIスレッドのブロックが発生しないようになります。