我运行一个包含两个项目的解决方案:应用程序和sdk。
通过这个应用程序,我创建了一个sdk实例,以便应用程序可以启动。问题是,当我在任务内部运行的代码中有一个异常时,就不会抛出未处理的异常,所以我的应用程序继续运行,并且没有意识到SDK中发生了意想不到的事情。
我在App中注册了AppDomain.CurrentDomain.UnhandledException的事件,但是正如在任务中抛出异常时所说的那样,事件处理程序不会被调用。
我遗漏了什么吗?
发布于 2015-01-12 22:39:09
这两个答案都有点完整(但不完全)。
异步
处理错误任务的最佳方法是异步等待,等待使用await完成任务。这将重新引发原始存储的异常:
try
{
await task;
}
catch (Exception e)
{
// handle exception
}同步
如果您不能这样做(或者不想这样做),您也可以使用AggregateException,它同步等待并抛出一个包含InnerExceptions中原始异常的,或者注册一个处理它的延续(即task.ContinueWith(t => // handle exception))。
UnobservedTaskException
在.Net 4.0中,一个未观察到的任务异常会降低整个过程。TaskScheduler.UnobservedTaskException事件是在崩溃之前处理异常的最后一个选项(非常类似于UnhandledException的情况)。在.Net 4.5中,这种类型的异常不再会导致应用程序崩溃,但事件仍然会引发。
如果你想让这个应用崩溃(我怀疑你会这么做),你可以设置<ThrowUnobservedTaskExceptions enabled="true"/>,就像Yuval指出的那样。您可以使用事件本身来处理异常,这不是最优的,原因有两个:
结论
确保await您的任务,以处理异常发生。还可以使用UnobservedTaskException作为捕获,以防您错过了任务。
发布于 2015-01-12 12:20:57
当Task抛出未处理的异常时,它的执行将被终止,您可以检查原始Task对象上的IsFaulted和Exception属性。
关于这些属性这里和这里的更多信息,还有一篇文章专门讨论任务关于MSDN中的异常处理
您还可以在UnobservedTaskException上使用TaskScheduler事件。我自己从来没有使用过它,但是读到它,它应该类似于UnhandledException事件在AppDomain上。检查它,论MSDN
发布于 2015-01-12 12:47:12
问题是,当我在任务内部运行的代码中有一个异常时,就不会抛出未处理的异常,所以我的应用程序继续运行,并且没有意识到SDK中发生了意想不到的事情。
这并不完全正确(由于@l3arnon进行了更正):Task将在.NET 4.0和.NET 4.5中传播异常,并触发UnobservedTaskException。两者的不同之处在于,.NET 4.5会在异常触发后悄悄吞下异常,而不是.NET 4.0,如果该事件得不到处理,它将使您的进程崩溃。
您可以通过您的'app.configandThrowUnobservedTaskExceptions`更改回.NET 4.0行为
有几种其他方法可以解决这个问题:
await Task.Run。await将从任务内部展开异常。https://stackoverflow.com/questions/27901852
复制相似问题