簡體   English   中英

Task.WaitAll,如何找到導致 AggregateException 的任務

[英]Task.WaitAll, how to find the tasks causing AggregateException

假設我得到了以下代碼:

var tasks = BuildTaskList();
try
{
    Task.WaitAll(tasks.ToArray());
}
catch (AggregateException exception)
{

}

我怎么知道哪個任務在 exception.InnerExceptions 中拋出了哪些exception.InnerExceptions

您仍然擁有Tasks列表,並且每個Task都有一個Exception屬性。 使用它,您可以確定哪些異常屬於哪個Task

但是,如果可以,最好使用Task.WhenAllTaskFactory.ContinueWhenAll不是阻塞等待。

var throwers = tasks.Where(task => task.Exception != null);
        var t1 = Task.Factory.StartNew(() => Console.WriteLine("Task 1"));
        var t2 = Task.Factory.StartNew(() => Console.WriteLine("Task 2"));
        var t3 = Task.Factory.StartNew(() => { throw new InvalidOperationException(); });
        var t4 = Task.Factory.StartNew(() => Console.WriteLine("Task 4"));

        Task.Factory.ContinueWhenAll(new[] { t1, t2, t3, t4 }, tasks =>
            {
                foreach (var t in tasks)
                {
                    if (t.Status == TaskStatus.Faulted)
                    {
                        // this will run for t3
                        Console.WriteLine("This task has been faulted.");
                    }
                }
            });

選項1(歸功於@theodor-zoulias 評論):

您可以使用任務名稱設置Exception.Data屬性:

var task1 = Task.Factory.StartNew(() =>
{
    try
    {
        throw new Exception();
    }
    catch (Exception exception)
    {
        exception.Data["task"] = "task1";
        throw exception;
    }
});

var task2 = Task.Factory.StartNew(() =>
{
    try
    {
        throw new Exception();
    }
    catch (Exception exception)
    {
        exception.Data["task"] = "task2";
        throw exception;
    }
});

try
{
    Task.WaitAll(task1, task2);
}
catch (AggregateException ae)
{
    foreach (var exception in ae.InnerExceptions)
    {
        Console.WriteLine($"Exception was thrown by {exception.Data["task"]}");
    }
}

選項2:

如果您不介意丟失異常程序集信息的名稱,您可以根據任務名稱設置拋出異常的Exception.Source ( doc ) 屬性並在迭代時查看它:

var t1 = Task.Factory.StartNew(() => 
{
    throw new Exception() { Source = "t1" };
});
var t2 = Task.Factory.StartNew(() => 
{
    throw new Exception() { Source = "t2" };
});

try
{
    Task.WaitAll(t1, t2);
}
catch (AggregateException ae)
{
    foreach (var exception in ae.InnerExceptions)
    {
        Console.WriteLine($"Exception was thrown by {exception.Source}");
    }
}

將輸出:

異常被 t1 拋出

異常被 t2 拋出

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM