Async CTP arasındaki Task.WaitAll()ve Task.WhenAll()Async CTP arasındaki fark nedir ? Farklı kullanım örneklerini göstermek için bazı örnek kodlar sağlayabilir misiniz?
Async CTP arasındaki Task.WaitAll()ve Task.WhenAll()Async CTP arasındaki fark nedir ? Farklı kullanım örneklerini göstermek için bazı örnek kodlar sağlayabilir misiniz?
Yanıtlar:
Task.WaitAll her şey tamamlanana kadar mevcut iş parçacığını engeller.
Task.WhenAllher şey tamamlanana kadar bekleme eylemini temsil eden bir görev döndürür .
Bu, zaman uyumsuz bir yöntemden şunları kullanabileceğiniz anlamına gelir:
await Task.WhenAll(tasks);
... yani her şey tamamlandığında yönteminiz devam edecek, ancak o zamana kadar takılmak için bir ileti dizisi bağlamayacaksınız.
WhenAll , ancak iş parçacığını engellemekle aynı şey değil.
JonSkeet'in cevabı, farkı tipik olarak mükemmel bir şekilde açıklarken, başka bir fark daha vardır: istisna yönetimi .
Task.WaitAllBir atar AggregateExceptiongörevlerden herhangi birini atar ve tüm atılan istisnalar inceleyebilir zaman. awaitİçinde await Task.WhenAllunwraps AggregateExceptionve 'döner' sadece ilk istisna.
Aşağıdaki program await Task.WhenAll(taskArray)çıktı ile yürütüldüğünde aşağıdaki gibidir.
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.
Aşağıdaki program çıktıyla yürütüldüğünde Task.WaitAll(taskArray)çıktı aşağıdaki gibidir.
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.
Program:
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);
awaitiki yöntem arasındaki fark değil, bir eser olduğunu düşünüyorum . Her ikisi de AggregateExceptiondoğrudan ya da bir mülk ( Task.Exceptionmülk) aracılığıyla bir a yayar .
Farkın bir örneği olarak - bir göreve sahipseniz Task.WaitAll(), kullanıcı arayüzü iş parçacığı engellenir ve kullanıcı arayüzü hiçbir zaman güncellenmezse , UI iş parçacığıyla bir şey yapar (örneğin, bir Öykü Tahtasında bir animasyonu temsil eden bir görev) . kullanırsanız await Task.WhenAll(), UI iş parçacığı engellenmez ve UI güncellenir.
Onlar ne yapar:
Fark ne:
Aşağıdakileri kullanın:
WaitAllAnladığım kadarıyla bu olasılığınız yok.
Task.WaitAll yaptıktan sonra sadece aramayı değiştirmez miydin? Yani, görevlerine başladıktan hemen sonra aramak yerine.