【发布时间】:2014-05-08 07:10:58
【问题描述】:
我见过的一个常见问题是在任务中管理未处理的异常。它们不会导致崩溃,它们会默默地发生,当任务失败时我什至无法触发事件!我见过用户开出自定义类和东西来处理这个问题,我的问题是,有没有“标准”的微软方法来处理这个问题?
为了举例,我制作了这个简单的控制台应用程序 (.NET 4.5.1) 来演示这个问题。是否可以对其进行修改,以便这些任务可以异步执行,但在遇到未处理的异常时调用“处理程序”?或者至少崩溃?我认为这正是 UnobservedTaskException 应该做的。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication4
{
class Program
{
static void Main(string[] args)
{
TaskScheduler.UnobservedTaskException += Handler;
AppDomain.CurrentDomain.UnhandledException += Handler;
Task.Run(() => { throw new ApplicationException("I'll throw an unhandled exception"); });
Task.Factory.StartNew(() => { throw new ApplicationException("I'll throw an unhandled exception too"); });
System.Threading.Thread.Sleep(2000);
Console.WriteLine("I think everything is just peachy!");
System.Threading.Thread.Sleep(10000);
}
private static void Handler(Object sender, EventArgs e)
{
Console.WriteLine("I'm so lonely, won't anyone call me?");
}
}
}
输出:
I think everything is just peachy!
期望的输出:
I'm so lonely, won't anyone call me?
I'm so lonely, won't anyone call me?
I think everything is just peachy!
和/或简单地崩溃,即使这将是对异步任务静默失败的巨大改进!
编辑:根据这篇 MSDN 文章 http://msdn.microsoft.com/en-us/library/jj160346%28v=vs.110%29.aspx 将此添加到 app.config,但没有更改:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<ThrowUnobservedTaskExceptions enabled="true"/>
</runtime>
</configuration>
【问题讨论】:
-
关于您的编辑,Reed 的答案和我上面链接的答案都解释了为什么没有变化:任务需要获得 GC'ed。这背后有充分的理由,请阅读链接了解更多详情。
-
我可以看出一切都是有原因的,但我不能否认有充分的理由不应该按设计发生的想法让我大吃一惊。如果我不想等待任务怎么办,在这种情况下我是否应该永远不要使用任务类而使用其他类呢?如果我确实需要等待,那么拥有一个可以订阅的事件有什么缺点?我要写一个扩展方法,一定要告诉我为什么不应该这样……
-
我已回复您的评论here。