当我调用ContinueWhenAll(...)
时,任务中未观察到的异常被完全隐藏。不会引发UnobservedTaskException
事件,也不会杀死应用程序。我等了几个小时。
我当然放下以下
<runtime>
<ThrowUnobservedTaskExceptions enabled="true"/>
</runtime>
进入配置文件。
如果我发表评论ContinueWhenAll
,则会引发事件并且应用程序很快被杀死。此外,简单的延续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);
}
}
答案 0 :(得分:1)
您的测试存在问题。即使使用UnobservedTaskException
,我也无法获得Task.ContinueWith
但是当我将任务解压缩到不同的方法时,会在Task.ContinueWith
上引发事件。 Task.Factory.ContinueWhenAll
(正如Sriram Sakthivel指出的那样,在发布模式下构建也会产生相同的效果):
static void Main()
{
TaskScheduler.UnobservedTaskException += (s, e) =>
{
Console.WriteLine("From unobserved exception handler: {0}", e.Exception.Message);
};
RunTask();
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);
}
}
static void RunTask()
{
var faultedTask = Task.Factory.StartNew(() => { throw new Exception("Task is faulted"); });
// 1. ContinueWhenAll hides unobserved exception
Task.Factory.ContinueWhenAll(new[] { faultedTask }, ts =>
{
Console.WriteLine("From \"when all\" continuation");
});
// 2. Simple continuation does not hide unobserved exception
//faultedTask.ContinueWith(t => { Console.WriteLine("From \"simple\" continuation"); });
}
所以,你没有得到这个例外的原因只是Task
还没有GC。