web-dev-qa-db-ja.com

コールスタックでawaitキーワードを1回省略すると、スタック全体の非同期動作が中断されますか?

呼び出しスタックには、Taskを返すいくつかのメソッドが含まれている場合があります。それらすべてがasyncで装飾されている場合、実行のフローは非常に単純です。ただし、そのうちの1つがawaitedでない場合、そのメソッドからの他のメソッド呼び出しは非同期で実行されているかどうかを確認してください。

次に例を示します。

私が持っている場合

_async Task A()
{
    ...
    await B();
    ...
}
_

A();ではなくawait (A);を呼び出すと、await B();が待機されますか?

5
nicks

.netでは、async awaitキーワードはTask Parallel Libraryの拡張です。 awaitasyncメソッドを使用しない場合、Task.Run(()=>A())を呼び出すのとほぼ同じです。

(UIスレッドやその他のシングルスレッドアプリケーションに関する問題があります。.ConfigureAwait(false)を使用しない場合、タスクを作成すると、待機中のコードが同じスレッドコンテキストでピックアップしようとします。バックグラウンドから待機している場合その後、ワーカースレッドコンテキストが待機し、Task.Run()が同じコンテキストで実行されます。UIスレッドを使用している場合、Task.Run()のコンテキストと待機中のコンテキストは異なります。)

あなたの例ではA()が開始し、await B()で制御を返し、次にA()を呼び出すコードがA()が待機している間に続行しますB()完了します。

簡単な例は次のとおりです。

static void Main(string[] args)
{
    Console.WriteLine("Starting main");

    A();

    Console.WriteLine("Finished Main");

    //dont end before A() finishes.
    Console.ReadLine();
}

static async Task A()
{
    Console.WriteLine("starting A");

    await B();

    Console.WriteLine("Finishing a");
}

static async Task B()
{
    //Add a delay before the Console.WriteLine
    await Task.Delay(1000);

    Console.WriteLine("starting B");

    await Task.Delay(1000);

    Console.WriteLine("Finishing b");
} 

MainメソッドがA()を呼び出すと、実行はawait B()まで逐次実行されます。 A()呼び出しが待機した後、制御はメインに戻り、終了します。この時点で、A()はまだ「Fire and Forget」を実行しているため、コンソールプログラムの場合は問題なので、A()の前にメインスレッドが完了しないことを確認する必要があります。終了します。 Console.ReadLine();がない場合、プログラムはA()awaitの呼び出し後に終了します。

4