[英]Catching exceptions thrown within a Task?
I am trying to catch exceptions within a Task
I have created but they never "bubble up" to where the Task
is ran from, they are always caught by Visual Studio as runtime errors. 我正在尝试在我创建的
Task
捕获异常,但是它们从未“冒泡”到运行该Task
位置,它们总是被Visual Studio捕获为运行时错误。
Here is a SSCCE I have created to show the issue 这是我创建的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 notifies me when I throw FooExcepion
in DoSomething
that the exception is not being caught. 当我在
DoSomething
中抛出FooExcepion
时,Visual Studio通知我未捕获到异常。 From this SO answer and this MSDN page I thought that the exceptions would just "bubble up" to myTask.Wait()
and subsequently be caught. 从这个SO答案和这个MSDN页面,我认为这些异常只会“冒泡”到
myTask.Wait()
并随后被捕获。 Though this does not seem to be that case. 尽管似乎并非如此。
The project settings for this SCCEE are targeting .NET 4.5.2 and I am using Visual Studio 2015. Is it that my targeted .NET framework cannot catch exceptions in this manner? 此SCCEE的项目设置的目标是.NET 4.5.2,而我正在使用Visual Studio2015。我的目标.NET框架是否无法以这种方式捕获异常? How can I catch
FooException
in the try/catch
block within Main
? 如何在
Main
的try/catch
块中捕获FooException
?
EDIT: I have altered the SSCCE to use the async
/ await
pattern instead of Task.Wait
. 编辑:我已经更改了SSCCE以使用
async
/ await
模式代替Task.Wait
。
Hit the Continue
button, you will see that the exception does get caught in the outer try/catch. 点击
Continue
按钮,您将看到异常确实被外部try / catch捕获。 Because the exception crossed in to the innards of Task
the exception was considered "User Unhanded", however Task
handels it for you by putting the task in to the Faulted
state. 因为异常越过中的内脏
Task
异常被认为是“用户Unhanded”,但Task
通过将任务到HANDELS为您Faulted
状态。 This will a exception to be re-raised when you await
or .Wait()
the task. 当您
await
或.Wait()
任务时,将重新引发此异常。
Using your original method before your edit would need to do 在编辑之前需要使用原始方法
try
{
myTask.Wait();
}
catch(AggregateException ex)
{
var innerException = ex.InnerException;
Console.Out.WriteLine("Exception of type " + innerException .GetType() + " caught, message: " + innerException.Message);
}
Because the Task will wrap the exceptions up in to a AggregateException
, when you use await
it unwraps the exception for you. 因为Task会将异常包装到
AggregateException
,所以当您使用await
,它将为您解包装异常。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.