【发布时间】:2014-03-19 16:54:58
【问题描述】:
我的应用程序有全局异常处理程序(好吧,记录器,我知道他们在技术上不会“处理”它们),它们就像:
public static class UnhandledExceptionHandler
{
public static void Init()
{
AppDomain.CurrentDomain.UnhandledException += OnCurrentDomainOnUnhandledException;
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
Application.ThreadException += ApplicationOnThreadException;
}
private static void ApplicationOnThreadException(object sender, ThreadExceptionEventArgs e)
{
if (e.Exception != null)
MessageBox.Show(e.Exception.ToString());
}
private static void OnCurrentDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
var ex = e.ExceptionObject as Exception;
if (ex != null)
MessageBox.Show(ex.ToString());
}
}
在Main()是
UnhandledExceptionHandler.Init();
但我发现当 Task.ContinueWith 中发生未处理的异常时,不会引发这些事件。 Visual Studio 将它们识别为未处理,因为它们在调试器中突出显示。
例如,您可以简单地进行测试:
private void button1_Click(object sender, EventArgs e)
{
Task.Factory.StartNew(() => { })
.ContinueWith(t =>
{
throw new Exception("continue with exception");
});
}
您会注意到没有引发 MessageBox(也没有引发任何事件)。
只是为了证明它确实有效,以下将有效:
private void button2_Click(object sender, EventArgs e)
{
throw new Exception("click failed");
}
有人知道为什么和/或如何能够捕获和记录这些未处理的异常吗?
当然,我明白将 ContinueWith 内部的逻辑量保持在最低限度可能是有意义的,但它仍然可能发生。
目前是 .NET 4.0
【问题讨论】:
-
Task.Factory.StartNew/ContinueWith返回一个具有 Exception 属性的任务。 -
好的,但这不意味着在我上面的例子中我必须有 另一个 ContinueWith 然后我检查
t.Exception?那么我是否需要无限数量的 ContinueWith 以防万一:) -
只有当您过于认真地对待您的用户名时,编写无限数量的 ContinueWiths 才有意义。使用采用 TaskContinuationOptions.OnlyOnFaulted 的重载往往很有用。请避免编写即发即弃的代码。
-
很遗憾,我必须将带有 OnlyOnFaulted 的
ContinueWith添加到Task之后 任何其他ContinueWiths 以确保我处理异常。
标签: c# .net exception task-parallel-library