Task中的异常处理

时间:2025-01-11 20:07:44

最简单的方式

    var t = new Task(() => {
throw new Exception("unknow excption");
});
t.Start();
try
{
t.Wait();
}
catch (AggregateException e)
{
foreach (var item in e.InnerExceptions)
{
Console.WriteLine("异常类型\t{0}\n来自\t{1}\n异常内容\t{2}", item.GetType(), item.Source, item.Message);
}
}

缺点:这个会阻塞当前线程。下面是改进版

var t = new Task(() => {
throw new Exception("unknow excption");
});
t.Start();
var cat = t.ContinueWith(task =>
{
foreach (var item in task.Exception.InnerExceptions)
{
Console.WriteLine("异常类型\t{0}\n来自\t{1}\n异常内容\t{2}", item.GetType(), item.Source, item.Message);
}
}, TaskContinuationOptions.OnlyOnFaulted); //指定只应在延续任务前面的任务引发了未处理异常的情况下才安排延续任务
Console.WriteLine("主线程退出");
Console.ReadKey();

缺点:异常没有回到主线程。继续改进

var t = new Task(() => {
throw new Exception("unknow excption");
});
t.Start();
var cat = t.ContinueWith(task =>
{
throw task.Exception;
}, TaskContinuationOptions.OnlyOnFaulted); //指定只应在延续任务前面的任务引发了未处理异常的情况下才安排延续任务
Console.WriteLine("主线程退出");
Thread.Sleep();
//异常处理
try
{
cat.Wait();
}
catch (AggregateException e)
{
foreach (var item in e.InnerExceptions)
{
Console.WriteLine("异常类型\t{0}\n来自\t{1}\n异常内容\t{2}", item.InnerException.GetType(), item.InnerException.Source, item.InnerException.Message);
}
}