【发布时间】:2015-04-22 04:06:32
【问题描述】:
当我从任务中调用ContinueWhenAll(...) 时未观察到的异常被完全隐藏。 UnobservedTaskException 事件未引发且应用程序未终止。我等了几个小时。
当然我放了以下
<runtime>
<ThrowUnobservedTaskExceptions enabled="true"/>
</runtime>
进入配置文件。
如果我评论ContinueWhenAll call - 事件被引发并且应用程序很快被杀死。而且简单的延续ContinueWith 也不会隐藏未观察到的异常。
static void Main(string[] args)
{
TaskScheduler.UnobservedTaskException += (s, e) =>
{
Console.WriteLine("From unobserved exception handler: {0}", e.Exception.Message);
};
var faultedTask = Task.Factory.StartNew(() => { throw new Exception("Task is faulted"); });
// 1. ContinueWhenAll hides unobserved exception
Task.Factory.ContinueWhenAll(new Task[] { faultedTask }, ts =>
{
Console.WriteLine("From \"when all\" continuation");
});
// 2. Simple continuation does not hide unobserved exception
//faultedTask.ContinueWith(t => { Console.WriteLine("From \"simple\" continuation"); });
faultedTask = null;
int gcCounter = 0;
while (true)
{
// artifical memory consumption
int[][] a = new int[4096][];
for (int j = 0; j < 4096; j++ )
a[j] = new int[4096];
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
Console.WriteLine("Garbage collected: {0}", ++gcCounter);
Thread.Sleep(500);
}
}
【问题讨论】:
-
Continuations 本身不会观察到异常。斯蒂芬的comment here 也这么说。 Continuations 不会观察到任务的异常,包括 ContinueWhenAll。强制观察的一种简单方法是添加对 Task.WaitAll 的调用作为 ContinueWhenAll 委托的第一行;此时任务已全部完成,因此您只是在利用 WaitAll 的观察逻辑。 所以我不确定发生了什么。编辑:更新了我的评论
标签: c# .net exception-handling task-parallel-library