Was ist der Unterschied zwischen Task.WaitAll()
und Task.WhenAll()
vom Async CTP? Können Sie einen Beispielcode bereitstellen, um die verschiedenen Anwendungsfälle zu veranschaulichen?
Was ist der Unterschied zwischen Task.WaitAll()
und Task.WhenAll()
vom Async CTP? Können Sie einen Beispielcode bereitstellen, um die verschiedenen Anwendungsfälle zu veranschaulichen?
Antworten:
Task.WaitAll
blockiert den aktuellen Thread, bis alles abgeschlossen ist.
Task.WhenAll
Gibt eine Aufgabe zurück, die die Aktion des Wartens darstellt, bis alles abgeschlossen ist.
Das bedeutet, dass Sie mit einer asynchronen Methode Folgendes verwenden können:
await Task.WhenAll(tasks);
... was bedeutet, dass Ihre Methode fortgesetzt wird, wenn alles abgeschlossen ist, aber Sie werden bis dahin keinen Thread binden, um nur herumzuhängen.
WhenAll
, aber das ist nicht dasselbe wie das Blockieren des Threads.
Während die Antwort von JonSkeet den Unterschied auf typisch hervorragende Weise erklärt, gibt es einen weiteren Unterschied: die Ausnahmebehandlung .
Task.WaitAll
löst eine aus, AggregateException
wenn eine der Aufgaben ausgelöst wird, und Sie können alle ausgelösten Ausnahmen untersuchen. Das await
in await Task.WhenAll
packt das aus AggregateException
und gibt nur die erste Ausnahme zurück.
Wenn das folgende Programm mit await Task.WhenAll(taskArray)
der Ausgabe ausgeführt wird, ist dies wie folgt.
19/11/2016 12:18:37 AM: Task 1 started
19/11/2016 12:18:37 AM: Task 3 started
19/11/2016 12:18:37 AM: Task 2 started
Caught Exception in Main at 19/11/2016 12:18:40 AM: Task 1 throwing at 19/11/2016 12:18:38 AM
Done.
Wenn das folgende Programm mit Task.WaitAll(taskArray)
der Ausgabe ausgeführt wird, ist wie folgt.
19/11/2016 12:19:29 AM: Task 1 started
19/11/2016 12:19:29 AM: Task 2 started
19/11/2016 12:19:29 AM: Task 3 started
Caught AggregateException in Main at 19/11/2016 12:19:32 AM: Task 1 throwing at 19/11/2016 12:19:30 AM
Caught AggregateException in Main at 19/11/2016 12:19:32 AM: Task 2 throwing at 19/11/2016 12:19:31 AM
Caught AggregateException in Main at 19/11/2016 12:19:32 AM: Task 3 throwing at 19/11/2016 12:19:32 AM
Done.
Das Programm:
class MyAmazingProgram
{
public class CustomException : Exception
{
public CustomException(String message) : base(message)
{ }
}
static void WaitAndThrow(int id, int waitInMs)
{
Console.WriteLine($"{DateTime.UtcNow}: Task {id} started");
Thread.Sleep(waitInMs);
throw new CustomException($"Task {id} throwing at {DateTime.UtcNow}");
}
static void Main(string[] args)
{
Task.Run(async () =>
{
await MyAmazingMethodAsync();
}).Wait();
}
static async Task MyAmazingMethodAsync()
{
try
{
Task[] taskArray = { Task.Factory.StartNew(() => WaitAndThrow(1, 1000)),
Task.Factory.StartNew(() => WaitAndThrow(2, 2000)),
Task.Factory.StartNew(() => WaitAndThrow(3, 3000)) };
Task.WaitAll(taskArray);
//await Task.WhenAll(taskArray);
Console.WriteLine("This isn't going to happen");
}
catch (AggregateException ex)
{
foreach (var inner in ex.InnerExceptions)
{
Console.WriteLine($"Caught AggregateException in Main at {DateTime.UtcNow}: " + inner.Message);
}
}
catch (Exception ex)
{
Console.WriteLine($"Caught Exception in Main at {DateTime.UtcNow}: " + ex.Message);
}
Console.WriteLine("Done.");
Console.ReadLine();
}
}
await t1; await t2; await t3;
vsawait Task.WhenAll(t1,t2,t3);
await
und nicht als einen Unterschied zwischen den beiden Methoden. Beide verbreiten einen AggregateException
, entweder direkt oder durch eine Eigenschaft (die Task.Exception
Eigenschaft).
Als Beispiel für den Unterschied: Wenn Sie eine Aufgabe haben, führt dies etwas mit dem UI-Thread aus (z. B. einer Aufgabe, die eine Animation in einem Storyboard darstellt), wenn Sie Task.WaitAll()
dann den UI-Thread blockieren und die UI nie aktualisiert wird. Wenn Sie verwenden, await Task.WhenAll()
wird der UI-Thread nicht blockiert und die UI wird aktualisiert.
Was machen Sie:
Was ist der Unterschied:
Verwenden Sie welche, wenn:
WaitAll
wie ich es verstehe.
Task.WaitAll
nachdem du deine andere Arbeit erledigt hast? Ich meine, anstatt es gleich nach dem Start Ihrer Aufgaben aufzurufen.