このことを考慮、
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();
ラムダの例では、task.Wait()
を呼び出すとき、返される遅延タスクではなく、構築した新しいタスクを待機しています。希望の遅延を得るには、結果のタスクも待つ必要があります。
Task<Task> task = new Task<Task>(async () => {
await Task.Delay(1000);
});
task.Start();
task.Wait();
task.Result.Wait();
新しいタスクの作成を避け、2つのタスクの代わりに1つのタスクを処理するだけで済みます。
Func<Task> task = async () => {
await TaskEx.Delay(1000);
};
task().Wait();
TaskEx.RunEx
を使用する必要があります。
内部で内部タスクを待機することにより、async
でTaskPool
メソッドの実行をネイティブにサポートします。そうしないと、直面している問題が発生し、外側のタスクのみが待機し、明らかにすぐに完了し、待機する必要のあるタスクが残るか、場合によっては(さらに悪いことに)できないボイドラムダが残ります待った。
または、外側のタスクを正しく構築していれば(現在はそうではありません)、タスクを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;