2025年7月27日
WPFアプリケーション開発において、非同期処理を行う際にTask.Runを利用するケースはよくあります。しかし、その中でUIを更新しようとすると例外が発生します。この記事では、.NET Framework 4.7.2環境のWPFにおいて、Task.Run中に安全にUIを更新する方法を詳しく解説します。
WPFのUIスレッド(Dispatcherスレッド)は1つしかなく、UI要素の更新はこのスレッド上でのみ許可されています。一方、Task.Runはスレッドプール上で非同期処理を行うため、直接UIにアクセスするとInvalidOperationExceptionが発生します。
Task.Run内でUIを更新したい場合は、Dispatcher.InvokeやDispatcher.BeginInvokeを使ってUIスレッドに処理を戻します。
Task.Run(() =>
{
// 重い処理
Thread.Sleep(2000);
// UIスレッドでの更新
Application.Current.Dispatcher.Invoke(() =>
{
myTextBlock.Text = "処理が完了しました";
});
});
private void StartButton_Click(object sender, RoutedEventArgs e)
{
Task.Run(() =>
{
var result = SomeHeavyWork();
Application.Current.Dispatcher.Invoke(() =>
{
resultTextBox.Text = result;
});
});
}
private string SomeHeavyWork()
{
Thread.Sleep(3000);
return "重い処理完了";
}
WPFの非同期処理では、async/awaitを使うとより簡潔にUI更新が行えます。awaitの後は自動的にUIスレッドに戻るため、Dispatcherの記述が不要になります。
private async void StartButton_Click(object sender, RoutedEventArgs e)
{
string result = await Task.Run(() => SomeHeavyWork());
resultTextBox.Text = result;
}
| メソッド | 説明 |
|---|---|
Dispatcher.Invoke |
同期的にUIスレッドで実行。呼び出し元は処理が完了するまで待機します。 |
Dispatcher.BeginInvoke |
非同期的にUIスレッドで実行。呼び出し元はすぐに処理を続行します。 |
WinUI 3 / XAML の Grid.Width 設定方法
WinUI 3でMenuFlyoutをShowAtで表示する方法【コード付き解説】
MenuFlyout は WinUI 3 で便利なポップアップメニュー
WinUI 3の開発で混乱しがちな「空白のウィンドウ」と「空白のページ」の違い
PowerShellでMSIXアプリ(Storeアプリ)を起動する方法|AppUserModelIdとURIスキーム活用術
Microsoft Storeアプリ更新時のロールアウト設定まとめ
Microsoft純正の新しいコンソールエディタ「edit」が復活!| edit.exe インストール方法
Microsoft Authenticatorのオートフィル機能が2025年7月に終了
RuntimeBroker.exeとMsEdgeWebView2.exeとは?Windows 11のプロセスについて
PowerShellでGrapheme Clusterについて処理を考える
【Windows】Volta コマンドライン インストール | Node.jsをバージョン管理する方法
【C#】大容量ファイルを指定サイズ以下に分割する方法|.NET8対応コード付き
【C# .NET 8】ファイルから重複行を削除する2つの方法|Distinct vs HashSet
WinUI 3 ComboBoxの自作クラスバインドと選択イベント検出方法
System.Text.Json 9.0.0.0 で FileNotFoundException
C#で改行・カンマ入りのCSVを正しく読み込む方法【.NET8対応】
C#/.NET 8でDateTimeを日本時間でISO 8601形式に変換する方法