2019年1月16日 星期三

TPL TAP 1 透過 Task.Status 取得正在執行中的工作狀態


TPL TAP 1 透過 Task.Status 取得正在執行中的工作狀態

當需要進行 Task 非同步的計算,可以選擇這些方法:建立一個 Task 物件 ,呼叫該物件的 Task.Start 方法、或者使用 TaskFactory.StartNew 來取得一個 Task 物件,又或者可以使用 Task.Run 方法來啟動一個 Task 非同步工作。
在這篇文章的範例中,則是使用 Task.Run 靜態方法,建立一個委派非同步工作,不過,在這個委派方法中,則是只有一行的程式碼,那就是拋出一個例外異常;由於在 Task 工作內所發生的例外異常,會被 Task 物件捕捉起來,並不會造成該應用程式異常結束,不過,在設計這樣的應用程式的時候,該如何知道這個工作發生了例外異常呢?在 Task 物件內,可以透過 Task.Status 這個屬性來得知該工作的執行結果或者當時的狀態。
其中 Task.Status 共會有這些列舉值 : Canceled , Created , Faulted , RanToCompletion , Running , WaitingForActivation , WaitingForChildrenToComplete , WaitingToRun
在底下的範例程式碼中,在主執行緒下會先使用 Task.Run 建立一個非同步委派工作,接著,主執行緒會休息 800ms ,最後,會顯示這個工作物件的狀態與最後結果的相關屬性值,分別是:IsCompleted 表示這個工作已經正常執行完成、 IsCanceled 這個工作取消了、最後是 IsFaulted 表示這個工作在執行上產生了例外異常。
C Sharp / C#
var fooTask = Task.Run( () =>
{
    throw new Exception("發生了例外異常");
});
Thread.Sleep(800);
Console.WriteLine($"Status : {fooTask.Status}");
Console.WriteLine($"IsCompleted : fooTask.IsCompleted}");
Console.WriteLine($"IsCanceled : fooTask.IsCanceled}");
Console.WriteLine($"IsFaulted : {fooTask.IsFaulted}");
var exceptionStatusX = (fooTask.Exception == null) ?"沒有 AggregateException 物件" : "有 ggregateException 物件";
Console.WriteLine($"Exception : {exceptionStatusX}")
Console.WriteLine("Press any key for continuing...")
Console.ReadKey();
現在,透過 Visual Studio 2017 的除錯組態進行這個範例程式碼除錯與執行, 可以,竟然偶而會看到底下的輸出結果,也就是看到該工作的狀態為 WaitingForActivation,想要不看這樣不正常的結果,因此,當要執行這個範例程式碼,請不要使用 Visual Studio 2017 來進行執行,因為,這樣會有可能得到 fooTask 物件的 Status 狀態值為 WaitingForActivation,所以,請在命令提示字元視窗下來執行。
Console
Status : WaitingForActivation
IsCompleted : False
IsCanceled : False
IsFaulted : False
Exception : 沒有 AggregateException 物件
Press any key for continuing...
當把這個範例程式碼,直接透過 命令提示字元視窗下來執行,此時,就會看到了所期望的結果,這個非同步委派工作最後的工作狀態應該是 Faulted,並且 Exception 這個屬性是有物件的。
Console
Status : Faulted
IsCompleted : True
IsCanceled : False
IsFaulted : True
Exception : 有 AggregateException 物件
Press any key for continuing...


沒有留言:

張貼留言