72

このことを考慮、

Task task = new Task (async () =>{
    await TaskEx.Delay(1000);
});
task.Start();
task.Wait(); 

task.Wait()の呼び出しはタスクの完了を待たず、次の行がすぐに実行されますが、非同期ラムダ式をメソッド呼び出しにラップすると、コードは期待どおりに機能します。

private static async Task AwaitableMethod()
{
    await TaskEx.Delay(1000);    
}

その後(svickからのコメントに従って更新)

await AwaitableMethod(); 
4

2 に答える 2

94

ラムダの例では、 を呼び出すとtask.Wait()、それが返す遅延 Task ではなく、作成した新しい Task を待機しています。希望の遅延を得るには、結果のタスクも待機する必要があります。

Task<Task> task = new Task<Task>(async () => {
    await Task.Delay(1000);
});
task.Start();
task.Wait(); 
task.Result.Wait();

新しい Task を作成することを避け、2 つではなく 1 つの Task を処理することができます。

Func<Task> task = async () => {
    await TaskEx.Delay(1000);
};
task().Wait();
于 2012-10-24T10:00:10.553 に答える
8

を使用する必要がありますTaskEx.RunEx

内部タスクを内部的に待機することによりasync、 でのメソッドの実行をネイティブにサポートします。TaskPoolそうしないと、直面している問題に遭遇します。ここでは、外側のタスクのみが待機されており、明らかにすぐに完了し、まだ待機が必要なタスク、またはあなたの場合 (さらに悪いことに) 不可能な void ラムダが残ります。待っていた。

または、外側のタスクを正しく構築していれば、タスクを 2 回待機することもできます (現在はそうではありません)。

現在のコード (固定):

Task task = new Task<Task>(async () =>{
    await TaskEx.Delay(1000);
});

task.Start();
var innerTask = await task;
await innerTask;

TaskEx.RunEx の使用:

Task task = TaskEx.RunEx(async () =>{ // Framework awaits your lambda internally.
    await TaskEx.Delay(1000);
});

await task;
于 2012-10-24T10:31:46.433 に答える