[英]Tpl's Continuations and exceptions?
如果我有一個引發異常的任務,則可以在延續中檢查是否存在異常:
Task task1 = Task.Factory.StartNew (() => { throw null; });
Task task2 = task1.ContinueWith (ant => Console.Write (ant.Exception));
但我也知道:
如果一個前件引發並且延續無法查詢該前件的Exception屬性(並且該前件沒有等待),則該異常被視為未處理,並且該應用程序死亡 。
所以我嘗試了:
Task task1 = Task.Factory.StartNew (() => { throw null; });
Task task2 = task1.ContinueWith (ant => Console.Write (1));//1
但是應用程序沒有崩潰。
拜托,我想念什么?
發生了幾件不同的事情:
首先,如果對有故障的Task
調用Wait()
,它將始終引發異常,無論您是否已經觀察到它。 在您的代碼中,這意味着如果您從Main()
調用task.Wait()
,則整個應用程序將崩潰,因為Main()
有未處理的異常。
其次, .NET 4.5中Task
中未處理的異常的行為已更改 ,它們將不再導致應用程序崩潰。 本文還介紹了如何切換回原始行為。 如果您安裝了.Net 4.5,則這也適用於面向.Net 4.0的應用程序(例如,使用VS 2010構建的應用程序)。
第三,使用.net 4.0行為, 當Task
被垃圾回收時 ,應用程序崩潰(假定在此之前未觀察到異常)。 這是因為在此之前,您的代碼仍有機會觀察到該異常。
因此,以下代碼使應用程序崩潰(假設您已安裝.Net 4.5,則啟用了.Net 4.0行為):
static void Main()
{
Task.Factory.StartNew(() => { throw new Exception(); });
// give the Task some time to run
Thread.Sleep(100);
GC.Collect();
}
您的代碼沒有崩潰,因為在應用程序正常退出之前,GC沒有機會運行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.