답변:
Task.WaitAll
모든 것이 완료 될 때까지 현재 스레드를 차단합니다.
Task.WhenAll
모든 것이 완료 될 때까지 기다리는 동작을 나타내는 작업 을 반환합니다 .
즉, 비동기 메서드에서 다음을 사용할 수 있습니다.
await Task.WhenAll(tasks);
... 모든 것이 완료되면 메소드가 계속된다는 것을 의미하지만 그 시간까지 스레드를 묶지 않습니다.
WhenAll
하지만, 그 스레드를 차단 같은 아니에요.
JonSkeet의 답변은 차이점을 일반적으로 훌륭한 방법으로 설명하지만 또 다른 차이점은 예외 처리 입니다.
Task.WaitAll
이 발생 AggregateException
하는 작업 중 하나를 던져 모든 던져 예외를 검사 할 수 있습니다 때. 의 await
는 await Task.WhenAll
포장을 풀고 AggregateException
첫 번째 예외 만 '반환'합니다.
아래 프로그램 await Task.WhenAll(taskArray)
이 출력으로 실행될 때 다음과 같습니다.
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.
아래의 프로그램 Task.WaitAll(taskArray)
이 출력으로 실행될 때 다음과 같습니다.
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.
프로그램:
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
두 방법의 차이점이 아닌 의 인공물이라고 생각 합니다. 둘 다 AggregateException
직접 또는 속성 ( Task.Exception
속성)을 통해 던지는를 전파합니다 .
그들은 무엇을합니까:
차이점이 뭐야:
다음과 같은 경우에 사용하십시오.
WaitAll
내가 이해 한대로 그 가능성은 없습니다 .
Task.WaitAll
한 후에 전화를 달리지 않겠습니까 ? 당신의 작업을 시작한 직후에 전화하는 대신에.