39

私の知る限り、ランタイムが以下のステートメントに出くわすと、非同期で呼び出されるメソッドへのコールバックとして関数の残りの部分をラップします(someCall()この例では)。この場合、 :anotherCall()へのコールバックとして実行されます。someCall()

    await someCall();
    await anotherCall();

ランタイムを次のように実行できるかどうか疑問に思いますsomeCall()。非同期で呼び出し、すぐに呼び出し元のスレッドに戻ってから、anotherCall()同様に呼び出します(完了するのを待たずsomeCallに)。非同期で実行するにはこれらの2つのメソッドが必要であり、これらの呼び出しは単なるファイアアンドフォーゲットコールであると想定しているためです。

asyncand await(古いbegin/endメカニズムを使用しない)だけを使用してこのシナリオを実装することは可能ですか?

4

3 に答える 3

53

async / awaitには、となどの並列合成を支援するいくつかの演算子が含まれていWhenAllますWhenAny

var taskA = someCall(); // Note: no await
var taskB = anotherCall(); // Note: no await

// Wait for both tasks to complete.
await Task.WhenAll(taskA, taskB);

// Retrieve the results.
var resultA = taskA.Result;
var resultB = taskB.Result;
于 2011-08-30T13:58:18.620 に答える
7

最も簡単な方法は、おそらくこれを行うことです。

var taskA = someCall();
var taskB = someOtherCall();
await taskA;
await taskB;

結果の値が必要な場合、これは特に便利です。

var result = await taskA + await taskB;

だからあなたはする必要はありません taskA.Result

TaskEx.WhenAll2つが次々に待つよりも速いかもしれません。パフォーマンスの調査を行っていないのでわかりませんが、問題が発生しない限り、特に結果の値がわからない場合は、2つの連続した待機の方が読みやすいと思います。

于 2012-01-18T20:33:27.977 に答える
2

.NET 4.5を使用している場合、非同期CTPは不要になりました。非同期機能はコンパイラーによって実装されるため、.NET 4アプリで使用できますが、コンパイルするにはVS2012が必要です。

TaskExはもう必要ありません。CTPは既存のフレームワークを変更できなかったため、拡張機能を使用して、言語が5.0で処理することを実現しました。タスクを直接使用するだけです。

そこで、ここで、TaskExをTaskに置き換えて、コードを書き直しました(Stephen Clearyが回答)。

var taskA = someCall(); // Note: no await
var taskB = anotherCall(); // Note: no await

// Wait for both tasks to complete.
await Task.WhenAll(taskA, taskB);

// Retrieve the results.
var resultA = taskA.Result;
var resultB = taskB.Result;
于 2014-03-26T13:39:16.657 に答える