it-swarm.com.de

kann nicht asynchrone Lambda erwarten

Bedenken Sie,

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

Der Aufruf task.Wait () wartet nicht auf den Abschluss der Aufgabe und die nächste Zeile wird sofort ausgeführt. Wenn ich den asynchronen Lambda-Ausdruck jedoch in einen Methodenaufruf einbinde, funktioniert der Code wie erwartet.

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

dann (aktualisiert laut kommentar von svick)

await AwaitableMethod(); 
61
kennyzx

Wenn Sie in Ihrem Lambda-Beispiel task.Wait() aufrufen, warten Sie auf die neue Task, die Sie erstellt haben, und nicht auf die Verzögerungstask, die sie zurückgibt. Um die gewünschte Verzögerung zu erhalten, müssen Sie auch auf die resultierende Aufgabe warten:

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

Sie könnten vermeiden, eine neue Aufgabe zu erstellen, und statt zwei nur eine Aufgabe haben:

Func<Task> task = async () => {
    await TaskEx.Delay(1000);
};
task().Wait();
82
Joe Daley

Sie müssen TaskEx.RunEx.

Es unterstützt nativ das Ausführen von async Methoden auf dem TaskPool, indem intern auf die innere Aufgabe gewartet wird. Andernfalls werden Sie auf das Problem stoßen, mit dem Sie konfrontiert sind, bei dem nur die äußere Aufgabe erwartet wird, die offensichtlich sofort abgeschlossen wird und entweder eine Aufgabe zurücklässt, die noch abzuwarten ist, oder in Ihrem Fall (und noch schlimmer) eine leere Lambda, die nicht sein kann erwartet.

Alternativ können Sie die Aufgabe zweimal abwarten, vorausgesetzt, Sie konstruieren Ihre äußere Aufgabe korrekt (was Sie derzeit nicht sind).

Aktueller Code (fest):

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

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

Verwenden von TaskEx.RunEx:

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

await task;
6