TaskScheduler.UnobservedTaskException事件处理程序从未被触发 [英] TaskScheduler.UnobservedTaskException event handler never being triggered

查看:764
本文介绍了TaskScheduler.UnobservedTaskException事件处理程序从未被触发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在读一本书关于C#任务并行库,并有下面的例子,但TaskScheduler.UnobservedTaskException处理程序永远不会被触发。 ?谁能给我任何线索,为什么

  TaskScheduler.UnobservedTaskException + =(对象发件人,EventArgs的UnobservedTaskExceptionEventArgs)=> 
{
eventArgs.SetObserved();
((AggregateException)eventArgs.Exception).Handle(EX =>
{
Console.WriteLine(异常类型:{0},ex.GetType());
返回真;
});
};

任务任务1 =新的任务(()=>
{
抛出新的ArgumentNullException();
});

任务TASK2 =新建任务(()=> {
抛出新ArgumentOutOfRangeException();
});

task1.Start();
task2.Start();


{
Thread.sleep代码(5000)(task1.IsCompleted || task2.IsCompleted!);
}

Console.WriteLine(完成);
到Console.ReadLine();


解决方案

不幸的是,这个例子绝不会告诉你你的代码。如果一个任务得到由GC收集与异常不可观测的 UnobservedTaskException 只会发生 - 只要你持有到任务1 TASK2 ,GC将永远不会收集,你永远不会看到您的异常处理程序。



为了看到的 UnobservedTaskException 的行动,我想尝试下面的(人为的例子)的行为:

 公共静态无效的主要()
{
TaskScheduler.UnobservedTaskException + =(对象发件人,EventArgs的UnobservedTaskExceptionEventArgs)=>
{
eventArgs.SetObserved();
((AggregateException)eventArgs.Exception).Handle(EX =>
{
Console.WriteLine(异常类型:{0},ex.GetType());
返回真;
});
};

Task.Factory.StartNew(()=>
{
抛出新的ArgumentNullException();
});

Task.Factory.StartNew(()=>
{
抛出新ArgumentOutOfRangeException();
});


Thread.sleep代码(100);
GC.Collect的();
GC.WaitForPendingFinalizers();

Console.WriteLine(完成);
Console.ReadKey();
}

这将显示您的邮件。第一个 Thread.sleep代码(100)调用提供足够的时间的任务扔。在收集和等待强制GC收集,这将触发事件处理程序2倍。


I'm reading through a book about the C# Task Parallel Library and have the following example but the TaskScheduler.UnobservedTaskException handler is never being triggered. Can anyone give me any clues as to why?

TaskScheduler.UnobservedTaskException += (object sender, UnobservedTaskExceptionEventArgs eventArgs) =>
{
    eventArgs.SetObserved();
    ((AggregateException)eventArgs.Exception).Handle(ex =>
    {
        Console.WriteLine("Exception type: {0}", ex.GetType());
        return true;
    });
};

Task task1 = new Task(() => 
{
    throw new ArgumentNullException();
});

Task task2 = new Task(() => {
    throw new ArgumentOutOfRangeException();
});

task1.Start();
task2.Start();

while (!task1.IsCompleted || !task2.IsCompleted)
{
    Thread.Sleep( 5000 );
}

Console.WriteLine("done");
Console.ReadLine();

解决方案

Unfortunately, that example will never show you your code. The UnobservedTaskException will only happen if a Task gets collected by the GC with an exception unobserved - as long as you hold a reference to task1 and task2, the GC will never collect, and you'll never see your exception handler.

In order to see the behavior of the UnobservedTaskException in action, I'd try the following (contrived example):

public static void Main()
{
    TaskScheduler.UnobservedTaskException += (object sender, UnobservedTaskExceptionEventArgs eventArgs) =>
                {
                    eventArgs.SetObserved();
                    ((AggregateException)eventArgs.Exception).Handle(ex =>
                    {
                        Console.WriteLine("Exception type: {0}", ex.GetType());
                        return true;
                    });
                };

    Task.Factory.StartNew(() =>
    {
        throw new ArgumentNullException();
    });

    Task.Factory.StartNew(() =>
    {
        throw new ArgumentOutOfRangeException();
    });


    Thread.Sleep(100);
    GC.Collect();
    GC.WaitForPendingFinalizers();

    Console.WriteLine("Done");
    Console.ReadKey();
}

This will show you your messages. The first Thread.Sleep(100) call provides enough time for the tasks to throw. The collect and wait forces a GC collection, which will fire your event handler 2x.

这篇关于TaskScheduler.UnobservedTaskException事件处理程序从未被触发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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