WPF Task.Run UI更新

【WPF】Task.Run中にUIを更新する方法(.NET Framework 4.7.2対応)

2025年7月27日

WPFアプリケーション開発において、非同期処理を行う際にTask.Runを利用するケースはよくあります。しかし、その中でUIを更新しようとすると例外が発生します。この記事では、.NET Framework 4.7.2環境のWPFにおいて、Task.Run中に安全にUIを更新する方法を詳しく解説します。

なぜTask.Run中にUIが更新できないのか?

WPFのUIスレッド(Dispatcherスレッド)は1つしかなく、UI要素の更新はこのスレッド上でのみ許可されています。一方、Task.Runはスレッドプール上で非同期処理を行うため、直接UIにアクセスするとInvalidOperationExceptionが発生します。

解決方法:Dispatcherを使ってUIスレッドに戻す

Task.Run内でUIを更新したい場合は、Dispatcher.InvokeDispatcher.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 "重い処理完了";
}
    

代替手段:async/awaitを使って簡潔に書く

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とBeginInvokeの違い

メソッド 説明
Dispatcher.Invoke 同期的にUIスレッドで実行。呼び出し元は処理が完了するまで待機します。
Dispatcher.BeginInvoke 非同期的にUIスレッドで実行。呼び出し元はすぐに処理を続行します。

WinUI 3 / XAML の Grid.Width 設定方法

WinUI 3でMenuFlyoutをShowAtで表示する方法【コード付き解説】

MenuFlyoutWinUI 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

【C#】.emlファイルの本文を読みやすく抽出する方法

WinUI 3 ComboBoxの自作クラスバインドと選択イベント検出方法

switch文でオブジェクトの型を判別する方法

【WPF】Task.Run中にUIを更新する方法

System.Text.Json 9.0.0.0 で FileNotFoundException

C#で改行・カンマ入りのCSVを正しく読み込む方法【.NET8対応】

C#/.NET 8でDateTimeを日本時間でISO 8601形式に変換する方法

Windows 11でタスクマネージャー以外からアプリを終了させる方法【PowerShell・コマンドプロンプト】

和暦設定でも安心!C#でISO 8601やカスタム日時文字列を確実にDateTimeに変換