ワーカースレッドのコードに、UI部品を更新するコードを書く(WPF)

もくじ
https://tera1707.com/entry/2022/02/06/144447

やりたいこと

WinUI3で、ワーカースレッドのコードに、UI部品を更新するコードを書くということを以前した。

tera1707.com

これと同じことをWPFでもしたい。

やりかた

Dispatcher.Invoke メソッド

もしくは

Dispatcher.BeginInvoke メソッド

を使う。

実験コード

別の実験をしていた時のコードなので余計なのがいろいろ入っているが、

この中の「dispatcher」を使っている部分がそれ。

dispatcher.Invoke()が、同期的に実行するやり方で、

dispatcher.BeginInvokeが、非同期的に実行するやり方。

using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;

namespace SyncroTest;

public partial class MainWindow : Window
{
    Dispatcher dispatcher = Dispatcher.CurrentDispatcher;
    private SynchronizationContext? Ctx { get => SynchronizationContext.Current; }
    private int ThId { get => Thread.CurrentThread.ManagedThreadId; }

    public MainWindow() => InitializeComponent();

    private async void Button_Click(object sender, RoutedEventArgs e)
    {
        //現在の(UIスレッドの)コンテキストを取得
        var context1 = Ctx;

        Debug.WriteLine($"Task.Run前:{ThId}");

        await Task.Run(() =>
        {
            Debug.WriteLine($"Task.Runの中:{ThId} 開始");
            
            context1?.Send(callback, "Send");
            dispatcher.Invoke(() => Debug.WriteLine($"dispatcher.Invoke : {ThId}"));//★コレ

            context1?.Post(callback, "Post");
            dispatcher.BeginInvoke(() => Debug.WriteLine($"dispatcher.BeginInvoke : {ThId}"));//★コレ
            
            Debug.WriteLine($"Task.Runの中:{ThId} 終了");
        });

        Debug.WriteLine($"Task.Run後:{ThId}");
        Debug.WriteLine($"");

        // ---------------------

        Debug.WriteLine($"context1 = Current? : {context1 == Ctx}");
        Debug.WriteLine($"");
    }

    private void callback(object? param)
    {
        Debug.WriteLine($"{param}{ThId}");
    }
}

参考

SynchronizationContext の実験

https://tera1707.com/entry/2024/04/22/225614

Dispatcher.Invoke メソッド

https://learn.microsoft.com/ja-jp/dotnet/api/system.windows.threading.dispatcher.invoke?view=windowsdesktop-8.0

もしくは

Dispatcher.BeginInvoke メソッド

https://learn.microsoft.com/ja-jp/dotnet/api/system.windows.threading.dispatcher.begininvoke?view=windowsdesktop-8.0