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.WhenAll
her ş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.WaitAll
Bir atar AggregateException
görevlerden herhangi birini atar ve tüm atılan istisnalar inceleyebilir zaman. await
İçinde await Task.WhenAll
unwraps AggregateException
ve '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);
await
iki yöntem arasındaki fark değil, bir eser olduğunu düşünüyorum . Her ikisi de AggregateException
doğrudan ya da bir mülk ( Task.Exception
mü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:
WaitAll
Anladığı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.