半人前プログラマーの技術談議

開発したもの紹介していくブログ

C# 非同期処理編 await part1-2

前回はTaskとasync修飾子で非同期メソッドが作成できる事と,

Task.Run()で別スレッドに処理を移し,並行して処理できる事がわかりました!

 

しかし,メインタスクでTask.Run()をするのは少々使い勝手が悪いです.

今回は,awaitを使ってこの問題を解消しようと思います.

 

 

 

 

awaitとは?

awaitが出てきたら,awaitを付けた非同期メソッドは別スレッドで処理が行われる.

 

awaitを使う条件として,async修飾子を付けた非同期メソッド内で書かなければならない.

1つの非同期メソッドにawaitは何個でも書くことができる.

 

説明だけではわかりにくいと思うので,実際に動かしてみます.

 

ソースコード

static void Main(string[] args)
{
    Console.WriteLine("メインタスクの処理開始");

    Console.WriteLine("メイン1");

    var task = SubTask();   // サブタスクを動かす

    Thread.Sleep(1 * 1000); // 1秒待機する
    Console.WriteLine("メイン2");

    Thread.Sleep(10 * 1000);    // 10秒待機する
    Console.WriteLine("メイン3");

    Console.WriteLine("メインタスクの処理完了");
}

static async Task SubTask()
{
    Console.WriteLine("サブタスクの処理開始");

    // 別スレッドでタスクを動かす
    var task = Task.Run(() =>
    {
        Console.WriteLine("サブ1");

        Thread.Sleep(5 * 1000);    // 5秒待機する
    });

    await task; //メインスレッドの処理がメインタスクに戻る

    Console.WriteLine("サブ2");

    Console.WriteLine("サブタスクの処理完了");
}

 

await task;は,別スレッドで動かしたタスクの処理が終わっていない場合,

メインスレッドの処理は,Mainメソッドのvar task = subTask();に戻る.

その後,別スレッドの処理が終わると,メインスレッドがawaitの後の処理を引き継ぎ,

それ以降の処理を行う.

この時,メインスレッドの処理が途中で終わっている場合は,

別スレッドが以降の処理を引き継ぐ事になる.

 

ソースコードに順序を書いてみたけど,ちょっとわかりにくいかも・・・

青がメインスレッドで,赤が別スレッドです.

f:id:pokoshirou:20180929162552p:plain

 

別スレッドの処理が完了したら,awaitによって,メインスレッドの処理から

の処理(await以降の処理)に移ります.

別スレッドメインスレッドの途中の処理から引き継がれます.

 

実行結果

f:id:pokoshirou:20180929155822p:plain

 

 

 

 

 

今回かなり短いですがここまでになります.

時間が無くて辛い(´・ω・`)