我运行的解决方案包含2个项目:app和sdk。
通过应用程序,我创建了一个sdk实例,以便应用程序可以启动。问题是,当我在Task内部运行的代码中遇到异常时,不会抛出Unhandled Exception,因此我的应用程序一直在运行,并且没有意识到SDK中发生了意外情况。
我已在App和SDK中注册了AppDomain.CurrentDomain.UnhandledException
的事件,但正如在任务中抛出异常时所述,事件处理程序未被调用。
我有什么遗失的东西吗?
答案 0 :(得分:5)
这两个答案都有些(但并非完全)完整。
处理故障任务的最佳方法是异步等待,以便使用await
完成。这将重新抛出原始存储的异常:
try
{
await task;
}
catch (Exception e)
{
// handle exception
}
如果你不能这样做(或者不想),你也可以使用task.Wait()
同步等待并抛出包含原始异常的 AggregateException
< / strong>在InnerExceptions
中或注册处理它的延续(即task.ContinueWith(t => // handle exception)
)
在.Net 4.0中,未观察到的任务异常会导致整个过程失效。 TaskScheduler.UnobservedTaskException
事件是崩溃前处理异常的最后一个选项(非常类似于UnhandledException
的情况)。在.Net 4.5中,这种类型的异常不再使应用程序崩溃,但事件仍然被提升。
如果你想在这种情况下崩溃应用程序(我怀疑你这样做),你可以设置<ThrowUnobservedTaskExceptions enabled="true"/>
,因为Yuval指出。您可以使用事件本身来处理因两个原因而不是最佳的异常:
确保await
您的任务在发生异常时处理。如果您错过任务,也可以使用UnobservedTaskException
作为捕获。
答案 1 :(得分:3)
当Task
抛出未处理的异常时,其执行将终止,您可以检查原始IsFaulted
对象上的Exception
和Task
属性。
有关这些属性的更多信息here和here,还有一篇专门讨论任务on the MSDN中的异常处理的文章
UnobservedTaskException
上还有TaskScheduler
个活动。我自己从未使用它,但阅读它,它应该与UnhandledException
上的AppDomain
事件类似。检查on MSDN
答案 2 :(得分:3)
问题是当我在代码运行的一部分中得到异常时 在任务内部,没有抛出未处理的异常,所以我的应用程序保持不变 运行并没有意识到SDK中发生了意外情况。
这不完全正确(感谢@ l3arnon进行更正):Task
将在.NET 4.0和.NET 4.5中传播异常,并将触发UnobservedTaskException
。两者之间的区别在于,.NET 4.5将在其触发后悄悄地吞下异常,而不是.NET 4.0,如果该事件未处理,将导致进程崩溃。
您可以通过&quot; app.config and
ThrowUnobservedTaskExceptions更改回.NET 4.0行为
还有其他几种方法可以解决这个问题:
await Task.Run
。 await
将从任务内部解开您的异常。如果您不想等待并想要使用&#34; Fire and Forget&#34;方法,你可以附上一个延续:
Task.Run(() => {}).ContinueWith(task => { */ Handle Exceptions here */ },
TaskContinutationOptions.OnlyOnFaulted);