我正在尝试使用ContinueWith()
包装异步任务可能抛出的异常。如果我只是从延续动作抛出事情似乎工作,但我的调试器声称异常未处理。我做错了什么或这是一个Visual Studio问题?有没有更简洁的方法来做到这一点,或者一种解决我的调试器停止最终处理的异常的方法?
下面的测试传递并打印“按预期捕获包装的异常”,但是当我调试它时,throw new CustomException
行显示为“未被用户代码处理”。
var task = DoWorkAsync().ContinueWith(t => {
throw new CustomException("Wrapped", t.Exception.InnerException); // Debugger reports this unhandled
}, TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.ExecuteSynchronously);
try {
task.Wait();
Assert.Fail("Expected work to fail");
} catch (AggregateException ag) {
if (!(ag.InnerException is CustomException))
throw;
}
Console.WriteLine("Caught wrapped exception as expected");
答案 0 :(得分:10)
当" Just My Code"启用后,Visual Studio在某些情况下会在抛出异常的行上中断,并显示一条错误消息,指出"异常不由用户代码处理。"这个错误是良性的。您可以按F5继续并查看这些示例中演示的异常处理行为。要防止Visual Studio在第一个错误中出现问题,只需取消选中" Just My Code" “工具”,“选项”,“调试”,“常规”下的复选框。
答案 1 :(得分:4)
您似乎没有用延续“包装”异常,您似乎在延续中抛出异常。如果DoWorkAsync是可以抛出异常的东西,我会按顺序“包装”它,如下所示:
DoWorkAsync().ContinueWith(t=>{
Console.WriteLine("Error occurred: " + t.Exception);
}, TaskContinuationOptions.OnlyOnFaulted);
或者,如果要在异步方法之外“处理”异常,可以这样做:
var task = DoWorkAsync();
task.Wait();
if(task.Exception != null)
{
Console.WriteLine("Error occurred: " + task.Exception);
}
如果要转换抛出的异常,可以执行以下操作:
var task = DoWorkAsync().ContinueWith(t=>{
if(t.Exception.InnerExceptions[0].GetType() == typeof(TimeoutException))
{
throw new BackoffException(t.Exception.InnerExceptions[0]);
}
}, TaskContinuationOptions.OnlyOnFaulted);
你可以这样处理BackoffException
:
if(task.IsFaulted)
{
Console.WriteLine(task.Exception.InnerExceptions[0]);
// TODO: check what type and do something other than WriteLine.
}