C#_戻り値が void と Task の違い

戻り値が void だと await がついた処理がいつ完了するかわからない。

 

await
Task 完了まで待つ、という意味なので同期的

await しない場合、「誰かこの仕事実行して」と命令を投げるだけなので
タスク実行中に自分は本来の仕事の続きをこなせる
戻り値 Task とすることで、その仕事の進捗状況を把握できる。

 

戻り値 Task
「手順書に書かれた仕事が全て完了したことを報告する」ことになる。
非同期メソッドで戻り値を Task にした場合、自動的に
メソッドが return した時に完了する Task となる。

 

戻り値 void
「この Task を開始して」という命令をした後は、その命令したことを忘れる
実害は、 void で実行した非同期メソッドの中で例外が発生した場合など、
その例外はコード上で見つけることが出来なくなり、アプリケーションを殺す。

 

 

各動作の違い

 

非同期メソッドで戻り値 Task

 

    private async Task Hoge( )    // 順次動作
    {
        await Task.Run(( ) => 処理A;
        //処理 A を実行する、というタスクを開始して完了するまで待機。
    }

return は?
非同期メソッドで戻り値が Task の時、そのメソッドが return した時に
完了する Task となる。
戻り値 Task と指定しても、返す必要がない ( 返せないもよう )。
Task <T> とすると、 return で T 型が返る。 

 

非同期メソッドで戻り値 void (基本 NG )

 

    private async void Hoge( )    // 順次動作
    {
        await Task.Run(( ) => 処理A;
        //処理 A の実行がいつ完了するか不明。完了するまで待機。
    }

 

同期メソッドで戻り値 void

 

    private void Hoge( )    // 並列動作
    {
        Task.Run(() => 処理A;
        // Task.Run が投げっぱ。処理 A の状態が分からない。
        //命令を投げるだけなので、
        //  処理 A 実行中に自分自身は本来の仕事の続きができる。
        //戻り値が Task だと進捗状況を把握できる。
    }

 

同期メソッドで戻り値 Task

 

    private Task Hoge( )    // 並列動作
    {
        var cs = new List<Fuga>;
        for(
        {
            var c = Task.Run(( ) => 処理A;
            cs.Add(c);    //処理 A を開始するというタスクを List にまとめる。
        }
        return Task.WhenAll(c);
        //全ての Task が完了した時、完了扱いになる Task を生成。
    }

 

 

async void は禁止

UI イベントハンドラ―に非同期メソッドを登録するのは void の必要があった。
UI から直接実行されるイベントの受け皿メソッドのみ、async void を使える。
それ以外は NG。 


特定のスレッドに依存する処理 ( UI 操作など ) は、
本来非同期メソッド上で取り扱ってはいけない。( Task の思想ではそうなるはずだった )

 

同期メソッドの戻り値 void は非同期メソッドでは戻り値 Task のこと。
同期メソッドの戻り値 T は非同期メソッドでは戻り値 Task<T> の T のこと。

 

 

こちらから。
https://qiita.com/acple@github/items/8f63aacb13de9954c5da
https://hiroronn.hatenablog.jp/entry/20171005/1507207811
https://qiita.com/tokishirazu/items/12c581f0ad4a6bcd562b

 

以上。いまいち分からんので後でソース書くと思う