「async」と「await」の使い方とタイミング 質問する

「async」と「await」の使い方とタイミング 質問する

私の理解では、asyncそしてawait目的はコードの書きやすさと読みやすさを向上させることですが、それらを使用することは、長時間実行されるロジックを実行するためにバックグラウンド スレッドを生成することと同じですか?

現在、最も基本的な例を試しています。インラインでコメントをいくつか追加しました。詳しく説明していただけますか?

// I don't understand why this method must be marked as `async`.
private async void button1_Click(object sender, EventArgs e)
{
    Task<int> access = DoSomethingAsync();
    // task independent stuff here

    // this line is reached after the 5 seconds sleep from 
    // DoSomethingAsync() method. Shouldn't it be reached immediately? 
    int a = 1; 

    // from my understanding the waiting should be done here.
    int x = await access; 
}

async Task<int> DoSomethingAsync()
{
    // is this executed on a background thread?
    System.Threading.Thread.Sleep(5000);
    return 1;
}

ベストアンサー1

を使用するとasyncawaitコンパイラはバックグラウンドでステート マシンを生成します。

ここで、何が起こっているのかを大まかに説明できる例を挙げます。

public async Task MyMethodAsync()
{
    Task<int> longRunningTask = LongRunningOperationAsync();
    // independent work which doesn't need the result of LongRunningOperationAsync can be done here

    //and now we call await on the task 
    int result = await longRunningTask;
    //use the result 
    Console.WriteLine(result);
}

public async Task<int> LongRunningOperationAsync() // assume we return an int from this long running operation 
{
    await Task.Delay(1000); // 1 second delay
    return 1;
}

さて、ここで何が起こるでしょうか:

  1. Task<int> longRunningTask = LongRunningOperationAsync();実行を開始するLongRunningOperation

  2. 独立した作業は、メイン スレッド (スレッド ID = 1) にawait longRunningTask到達すると仮定して実行されます。

    ここで、 がlongRunningTask終了しておらず、まだ実行中の場合は、MyMethodAsync()呼び出しメソッドに戻るため、メイン スレッドはブロックされません。 がlongRunningTask完了すると、ThreadPool のスレッド (任意のスレッド) がMyMethodAsync()以前のコンテキストに戻り、実行を続行します (この場合は、結果をコンソールに出力します)。

longRunningTask2 番目のケースは、 がすでに実行を終了していて、結果が利用できる場合です。 に到達したときにawait longRunningTaskはすでに結果があるため、コードはまったく同じスレッドで実行を続けます。 (この場合は、結果をコンソールに出力します)。 もちろん、 が関係する上記の例では、これは当てはまりませんTask.Delay(1000)

おすすめ記事