捕捉在任务中抛出的异常
本文关键字:异常 任务 | 更新日期: 2023-09-27 18:07:14
我试图在我创建的Task
中捕获异常,但它们从未"冒泡"到Task
运行的地方,它们总是被Visual Studio捕获为运行时错误。
这是我创建的一个SSCCE来显示这个问题
using System;
using System.Threading.Tasks;
namespace ConsoleApplicationSandbox
{
class Program
{
static void Main(string[] args)
{
CreateTheIssue();
Console.ReadLine();
}
public static async void CreateTheIssue()
{
try
{
int val = await ExceptionThrowerClass.DoSomething();
}
catch(Exception ex)
{
Console.Out.WriteLine("Exception of type " + ex.GetType() + " caught, message: " + ex.Message);
}
}
}
public static class ExceptionThrowerClass
{
public static Task<int> DoSomething()
{
return Task.Run(() =>
{
throw new FooException("How exceptional!");
return 1;
});
}
}
public class FooException : Exception
{
public FooException() : base () { }
public FooException(String message) : base(message) { }
public FooException(String message, Exception inner) : base (message, inner) { }
}
}
Visual Studio通知我,当我抛出FooExcepion
在DoSomething
,异常没有被捕获。从这个SO答案和这个MSDN页面,我认为异常只会"冒泡"到myTask.Wait()
,随后被捕获。尽管事实似乎并非如此。
这个SCCEE的项目设置是针对。net 4.5.2,我使用的是Visual Studio 2015。我的目标。net框架不能以这种方式捕获异常吗?如何在Main
内的try/catch
块中捕获FooException
?
编辑:我已经改变了SSCCE使用async
/await
模式而不是Task.Wait
。
点击Continue
按钮,您将看到异常确实在外部try/catch中被捕获。因为异常进入了Task
的内部,所以异常被认为是"User unhand",但是Task
通过将任务置于Faulted
状态来为您处理它。当您await
或.Wait()
执行任务时,将会重新引发异常。
在编辑之前使用原始方法
try
{
myTask.Wait();
}
catch(AggregateException ex)
{
var innerException = ex.InnerException;
Console.Out.WriteLine("Exception of type " + innerException .GetType() + " caught, message: " + innerException.Message);
}
因为Task会将异常封装到AggregateException
中,所以当您使用await
时,它会为您打开异常。