TaskScheduler.UnobservedTaskException事件处理程序从未被触发 [英] TaskScheduler.UnobservedTaskException event handler never being triggered
问题描述
我在读一本书关于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 $ C参$ C>和
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屋!