TaskScheduler.UnobservedTaskException不会被调用 [英] TaskScheduler.UnobservedTaskException never gets called

查看:266
本文介绍了TaskScheduler.UnobservedTaskException不会被调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据我的研究,我已经学会了以下内容:

Based on my research, I have learned the following:

  1. TaskScheduler.UnobservedTaskException 必须等待任务是垃圾的任务的不可观测异常之前收集将泡到 UnobservedTaskException 事件。
  2. 如果您使用的是 Task.Wait(),它永远不会得到反正叫,因为你在阻止即将发生的结果,从任务,因此,除了将在 Task.Wait抛出(),而不是泡到 UnobservedException 事件。
  3. 电话 GC.Collect的()手动通常是一个坏主意,除非你知道自己在做什么,所以这是很好的在这种情况下确认的东西,而不是为妥善解决这一问题。
  1. TaskScheduler.UnobservedTaskException must wait for the task to be garbage collected before that task's unobserved exception will bubble up to the UnobservedTaskException event.
  2. If you're using Task.Wait(), it'll never get called anyway, because you're blocking on an impending result from the Task, hence the exception will be thrown on Task.Wait() rather than bubble up to the UnobservedException event.
  3. Calling GC.Collect() manually is generally a bad idea unless you know exactly what you're doing, hence it's good in this case for confirming things, but not as a proper solution to the issue.

问题

如果我的应用程序退出之前,垃圾收集踢,我绝对100%不能让我的 UnobservedTaskException 事件触发。

If my application exits before the garbage collector kicks in, I absolutely 100% cannot get my UnobservedTaskException event to fire.

请注意以下code:

class Program
{
    static void Main(string[] args)
    {
        TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
        Task.Factory.StartNew(() =>
        {
            Console.WriteLine("Task started.");
            throw new Exception("Test Exception");
        });
        Thread.Sleep(1000);
        //GC.Collect();
        //GC.WaitForPendingFinalizers();
    }

    static void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
    {
        File.WriteAllText(@"C:\data\TestException.txt", e.Exception.ToString());
        Console.WriteLine("EXCEPTION UNOBSERVED");
    }
}

没有异常文件写入,并没有什么写入控制台。 10-15分钟,更可以在应用程序退出后去了,仍然我看到没有证据表明我的应用程序的遗体被垃圾收集。你可能会问,那么为什么不收集退出?好了,我的现实世界的情况是,我的异常捕获里面的Windows服务中托管的WCF服务运行。我可以在Windows服务正在关闭不陷阱(以及手动调用 GC.Collect的())因为没有事件说,就我所看到的。

No exception file is written and nothing is written to the console. 10-15 minutes and more can go by after the application exits and still I see no evidence that my application's remains were garbage collected. You might ask, well why not just collect on exit? Well, my real world scenario is that my exception trapping runs inside a WCF service hosted inside a Windows service. I cannot trap when the Windows service is shutting down (and hence manually call GC.Collect()) because there is no event for that as far as I can see.

我在哪里去了?如何确保,如果事情WCF服务内心深处是要最终打破我的窗口服务,我有机会服务翻倒之前,记录异常?

Where am I going wrong? How do I ensure that if something deep inside the WCF service is going to ultimately break my windows service, that I have a chance to log the exception before the service falls over?

推荐答案

对我来说,TaskScheduler.UnobservedTaskException首先给出了一个非常错误的安全感。这真是不值钱,如果它依赖于垃圾收集。

To me, TaskScheduler.UnobservedTaskException at first gives a very wrong sense of security. It's really not worth much if it depends on Garbage Collection.

我发现下面的解决方案,从拍摄这个MSDN文章,要可靠得多。它基本上执行的延续块(如登录的除外)唯一的,如果有在任务1未处理的异常,并不会阻塞UI执行。

I found the following solution, taken from this msdn article, to be much more reliable. It basically executes the continuation block (where you log the exception) only if there were unhandled exceptions in task1, and does not block UI execution.

您可能还需要扁平化嵌套AggregateExceptions也许创建扩展方法,如里德·科普塞这里描述。

You might also want to flatten nested AggregateExceptions and perhaps create a extension method, as Reed Copsey depicted here.

var task1 = Task.Factory.StartNew(() =>
{
    throw new MyCustomException("Task1 faulted.");
})
.ContinueWith((t) =>
{
    Console.WriteLine("I have observed a {0}",
        t.Exception.InnerException.GetType().Name);
},
TaskContinuationOptions.OnlyOnFaulted);

这篇关于TaskScheduler.UnobservedTaskException不会被调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆