非同期処理の考え方

2019年1月5日

非同期処理とは、2つ以上の処理を並行して実行することです。システム的には、複数のスレッドで処理を実行しています。
サンプルから概要を考えてみます。

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

これは、50回「メイン:XXの処理」と表示するコードですね。
では、次はどうでしょう。

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つの繰り返し処理を同時に実行させることはできるのでしょうか?
できます!非同期処理を使うことで実現可能です。
まず、メソッドを分けます。

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

そして、非同期に処理させるためのメソッドを追加します。

static async Task RunAsync()
{
    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の処理
サブ処理が終了しました

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

2019年1月5日C#,入門

Posted by hidepon