2013-08-22 15 views
0
var moduleTimeOut = 3000; 
var errorsThatOccurred = new List<string>(); 
List<string> names = new List<string>() { "Task1", "Task2", "Task3" }; 

var tasks = new List<Task<string>>(); 
names.ForEach(name => tasks.Add(Task<string>.Factory.StartNew((m) => MyTask(m.ToString()), name))); 

try 
{ 
    var allTasksCompletedInTime = Task.WaitAll(tasks.ToArray(), moduleTimeOut); 

} 
catch (AggregateException ex) 
{ 
    foreach (var exception in ex) 
    { 
     errorsThatOccurred.Add(exception.ToString()); 
    } 
} 
private string MyTask(string name) 
{ 
    if (name.Equals("Task1")) 
     System.Threading.Thread.Sleep(5000); 

    if (name.Equals("Task2")) 
     throw new ArgumentException("Task2 has thrown an exception"); 

    return "MyTask has finished the execution. Task is " + name; 
} 

AggregateException을 캡처하는 데 문제가 있습니다. 여기 내 다른 시나리오가 있습니다.Task.WaitAll throwing AggregateException 작업 중 하나가 실행 중일 때

  1. 모든 작업이 완료됩니다. → 잘 작동합니다.

  2. Task2에서 오류가 발생하고 다른 모든 작업이 완료됩니다. → AggregateException이 발생하여 Task2에 의해 Throw 된 ArgumentException을 볼 수 있습니다.

  3. Task1이 완료되지 않고 실행 중입니다. Task2가 오류를 발생시킵니다. 작업 3이 완료되었습니다. → AggregateException이 발생하지 않았습니다. Task2 상태가 오류가 발생하고 Exception 속성에 예외 정보가 표시됩니다.

왜 시나리오 3에서 AggregateException을 발생시키는 지 알 수 없습니다. 어떤 도움이 필요합니까?

답변

3

예상되는 동작입니다. 모든 작업이 완료되기 전에 시간 초과가 발생하면 (완료, 오류 또는 취소됨) 예외를 throw하지 않습니다. 단지 false를 반환합니다.

모든 작업이 할당 된 시간 내에 완료된 경우에만 예외가 throw됩니다.

+0

고마워요! 그러면이 경우 모든 예외를 어떻게 캡처해야합니까? 모든 예외를 포착하기 위해 모든 작업이 완료 될 때까지 기다릴 수는 없습니다. – user1186065

+0

@ user1186065 WaitAll로 전달한 각 작업의 상태를 살펴보고 오류가 발생한 작업을 추적해야합니다. 또는 대신 자신이 원하는 동작을하는 'WaitAll'을 자신 만의 버전으로 만들 수 있습니다. – Servy