【发布时间】:2018-06-26 11:06:25
【问题描述】:
在 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 运行,应用程序就不会崩溃。据我了解,一旦收集到任务,就应该抛出错误。
另请注意,我知道这个问题没有回答我的问题 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; }
});
}
我已经知道等待 Task 会导致应用崩溃。
【问题讨论】:
-
你的框架是什么,你设置了 ThrowUnobservedTaskExceptions 吗?
-
您没有在任何地方使用
async/await。您正在触发一个任务并且从不检查它是成功还是失败。如果你这样做了,即如果你写了await Task.Run(()=>throw new Exception(..));,那么这个异常将在await之后被重新抛出 -
如果您将
<ThrowUnobservedTaskExceptions>元素添加到您的配置文件并按第一个按钮,然后按第二个按钮,该过程应该会崩溃。这是预期的行为。看我的回答。 -
顺便说一句,应用程序不会崩溃,因为它不应该崩溃。未观察到的任务异常不会使应用程序崩溃
-
首先,不要更改默认行为,否则您可能会破坏依赖它的库。其次,查看TaskScheduler.UnobservedTaskException 事件的文档。它解释了
the process does not terminate by default在发生非观察者任务异常时。
标签: c# multithreading async-await task-parallel-library