簡體   English   中英

Tpl的延續和例外?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM