为什么抛出异常时应用程序不会崩溃
Why app doesn't crash when exception is thrown
在 WPF 应用程序中,我添加了两个按钮,一个用于启动任务,另一个用于强制 GC 运行:
private void Button_Click(object sender, RoutedEventArgs e)
{
Task.Run(() =>
{
throw new Exception("Some Exception");
});
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
GC.Collect();
GC.WaitForPendingFinalizers();
}
任务只是抛出一个异常。
当 运行在发布配置中启用应用程序时,我按了第一个按钮,然后按了第二个按钮,我预计应用程序会崩溃。这不会发生,无论我按下按钮多少次。
我知道 .NET 4.5 中未观察到的任务吞并异常的行为:https://blogs.msdn.microsoft.com/pfxteam/2011/09/28/task-exception-handling-in-net-4-5/
我很困惑,但是为什么一旦 GC 运行s,应用程序就不会崩溃。根据我的理解,一旦收集到任务,就应该抛出异常。
另请注意,我知道这个问题并没有回答我的问题
Why doesn't my process terminate when Task has unhandled exception?
答案标记的评论建议使用ContinueWith
,但这也不起作用,应用程序没有崩溃,异常被吞没:
private void Button_Click(object sender, RoutedEventArgs e)
{
Task.Run(() =>
{
throw new Exception("Some Exception");
}).ContinueWith(t =>
{
if (t.IsFaulted) { throw t.Exception.InnerException; }
});
}
我已经知道等待任务会使应用程序崩溃。
这是因为你火了就忘了。异常将发生在一个单独的线程中。如果你想让它崩溃,你必须 await
它或让它同步。
private void Button_Click(object sender, RoutedEventArgs e)
{
await Task.Run(() =>
{
throw new Exception("Some Exception");
});
}
I am confused however why once GC runs, the app doesn't crash. Per my understanding, Once the task is collected the eception should be thrown.
您的理解是正确的,前提是您通过向 App.config
添加以下元素来使用旧行为(.NET Framework 4.5 之前):
<runtime>
<ThrowUnobservedTaskExceptions enabled="true"/>
</runtime>
如果您不这样做,UnobservedTaskException
不会 导致进程崩溃。尽管仍然会引发异常,因此您可以在两种情况下处理 TaskScheduler.UnobservedTaskException
事件。
在 WPF 应用程序中,我添加了两个按钮,一个用于启动任务,另一个用于强制 GC 运行:
private void Button_Click(object sender, RoutedEventArgs e)
{
Task.Run(() =>
{
throw new Exception("Some Exception");
});
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
GC.Collect();
GC.WaitForPendingFinalizers();
}
任务只是抛出一个异常。
当 运行在发布配置中启用应用程序时,我按了第一个按钮,然后按了第二个按钮,我预计应用程序会崩溃。这不会发生,无论我按下按钮多少次。
我知道 .NET 4.5 中未观察到的任务吞并异常的行为:https://blogs.msdn.microsoft.com/pfxteam/2011/09/28/task-exception-handling-in-net-4-5/
我很困惑,但是为什么一旦 GC 运行s,应用程序就不会崩溃。根据我的理解,一旦收集到任务,就应该抛出异常。
另请注意,我知道这个问题并没有回答我的问题 Why doesn't my process terminate when Task has unhandled exception?
答案标记的评论建议使用ContinueWith
,但这也不起作用,应用程序没有崩溃,异常被吞没:
private void Button_Click(object sender, RoutedEventArgs e)
{
Task.Run(() =>
{
throw new Exception("Some Exception");
}).ContinueWith(t =>
{
if (t.IsFaulted) { throw t.Exception.InnerException; }
});
}
我已经知道等待任务会使应用程序崩溃。
这是因为你火了就忘了。异常将发生在一个单独的线程中。如果你想让它崩溃,你必须 await
它或让它同步。
private void Button_Click(object sender, RoutedEventArgs e)
{
await Task.Run(() =>
{
throw new Exception("Some Exception");
});
}
I am confused however why once GC runs, the app doesn't crash. Per my understanding, Once the task is collected the eception should be thrown.
您的理解是正确的,前提是您通过向 App.config
添加以下元素来使用旧行为(.NET Framework 4.5 之前):
<runtime>
<ThrowUnobservedTaskExceptions enabled="true"/>
</runtime>
如果您不这样做,UnobservedTaskException
不会 导致进程崩溃。尽管仍然会引发异常,因此您可以在两种情况下处理 TaskScheduler.UnobservedTaskException
事件。