C# WinUI 3におけるマルチスレッド

C# WinUI 3におけるマルチスレッドを説明する。

 マルチスレッドは同時に複数の処理を実行する仕組み。
 プログラムの実行はスレッドが担っており初めから存在するスレッドをメインスレッド、メインスレッドから生成するスレッドをサブスレッドと呼ぶ。

 本記事では以下2点を簡単に説明する。サンプルコードはおまけ。

    1. サブスレッドの実行(Taskとasync/await)
    2. サブスレッドからコントロール(TextBox等)へアクセス
    3. サンプルコード

本記事の内容を参考にする際はご自身の判断と責任のもとでお願いします。
本記事の内容を実践したことによるいかなる損害についても著者は一切の責任を負いかねます。予めご了承下さい。

1. サブスレッドの実行(Taskとasync/await)

 マルチスレッドを実装すると複雑なコードになりがちだがTaskとasync/awaitを使う事で容易に利用できるようになった。

 Taskとasync/awaitはWinUI 3に関係なく以前から利用することができる。

 以下にサブスレッドを実行するコードを示す。

async void StartSubThread()
{
    // awaitの呼び出し前はメインスレッドが実行を行う。

    // awaitでメソッドを呼び出すとそのメソッドの実行はサブスレッドが行う。
    // awaitでメソッドを呼び出す場合、awaitでメソッド呼び出しを行うメソッド(StartSubThread)は
    // asyncで定義する必要がある。

    await Task.Run(() =>
    {
        // ここはサブスレッドが実行を行う。

        Task.Delay(1000);  // ここは時間がかかる何かしらの処理。
    });

    // awaitの呼び出し後はスレッドプールのスレッドが実行を行う。
    // (メインスレッドとは限らない)

}

 Task.Runの引数 () => {} はラムダ式です。わからなければメソッドを定義した上でそのメソッド自体を引数として渡していると理解して下さい。(デリゲートをよりシンプルにしたイメージです)

2. サブスレッドからコントロール(TextBox等)へアクセス

 サブスレッドからコントロール(TextBox等)へ直接アクセスする事は出来ません。(アクセスしたら例外が発生する)
 サブスレッドからコントールへアクセスするためにはMicrosoft.UI.Dispatching.DispatcherQueueクラスのインスタンスメソッドTryEnqueueを使用する。
 サブスレッドとメインスレッドで変数を共有する場合はlock等で排他制御を行う必要がある。(排他制御は本記事では説明しない)

3. サンプルコード

  1. 実践的なサブスレッドの実行メソッド(TryEnqueueの使用)
  2. 実用的なサブスレッドの使用(サブスレッドの中断。アプリを閉じる時に必要なことも)

※ 実行には Visual Studio Community 2022 以上をインストールしておりC#Windows 11も問題なく扱える方が対象です。

この続きはcodocで購入