非同期処理の考え方

2022年2月10日

非同期処理とは、2つ以上の処理を並行して実行することです。これにより時間のかかる処理を待たずに続けることができるようになります。

サンプルとして、普通に50回「メイン:XXの処理」と表示する処理を考えてみます

static void Main(string[] args)
{
    for (int i = 0; i < 50; i++)
    {
        Console.WriteLine($"メイン:{i}の処理");
    }
 }

では、同様な処理をもう一つ実行したい場合を考えてみましょう

static void Main(string[] args)
{
    for (int i = 0; i < 50; i++)
    {
        Console.WriteLine($"メイン:{i}の処理");
    }
    for (int i = 0; i < 50; i++)
    {
        Console.WriteLine($"サブ:{i}の処理");
    }
}

50回「メイン:XXの処理」と表示した後、50回「サブ:XXの処理」と表示されるでしょう。
ここで、2つのループをそれぞれの別の処理と考え、同時に実行させるようにしたい場合について考えてみます

まず、2つ目の処理(サブ処理)をメソッドとして独立させます

static void Count()
{
    for (int i = 0; i < 50; i++)
    {
        Console.WriteLine($"サブ:{i}の処理");
    }
}

そして、非同期に処理させるためにサブ処理を呼ぶ処理をメソッドとして追加します

static async Task RunAsync()
{
    Console.WriteLine("サブ処理が開始されました");
    await Task.Run(() => Count());
    Console.WriteLine("サブ処理が終了しました");
}

async(エイシンク)とawait(アウェイト)が鍵です。
asyncは、処理を一旦、呼び出し元に戻す処理をします。
awaitは、続くTask.Runで引数で与えられたメソッドが完了するのを待ちます。この場合は、Count()メソッドになりますね。
次の行の"サブ処理が終了しました"は、Count()メソッドが完了後に表示されることになります。

Mainメソッドからは、次のように呼び出します。

Task subWork = RunAsync();

まとめると、

static void Main(string[] args)
{
    Task subWork = RunAsync();
    Console.WriteLine("メイン処理が開始されました");
    for (int i = 0; i < 50; i++)
    {
        Console.WriteLine($"メイン:{i}の処理");
    }
    Console.WriteLine("メイン処理が終了しました");
}
static async Task RunAsync()
{
    Console.WriteLine("サブ処理が開始されました");
    await Task.Run(() => Count());
    Console.WriteLine("サブ処理が終了しました");
}
static void Count()
{
    for (int i = 0; i < 50; i++)
    {
        Console.WriteLine($"サブ:{i}の処理");
    }
}

サブ処理が開始されました
メイン処理が開始されました
サブ:0の処理
メイン:0の処理
サブ:1の処理
メイン:1の処理
サブ:2の処理



メイン:48の処理
サブ:47の処理
メイン:49の処理
サブ:48の処理
メイン処理が終了しました
サブ:49の処理
サブ処理が終了しました

表示を確認してください。いかがでしょうか?非同期に処理がなされているのがわかりますね。

C#,入門

Posted by hidepon