備注:這篇文章的使用環境是.NET framework 4.0 RC 1
在WF4中創建native活動時,NativeActivity是非常強大的。其眾多的功能之一是圍繞錯誤處理。
調度子活動的時的基本錯誤處理。
??? 當NativeActivity執行的時候,它是通過一個NativeActivityContext實例,這個實例通過使用ScheduleActivity()函數來調度其他活動。ScheduleActivity()函數有幾個重載,其中一個使用了FaultCallback。當執行被調度的子活動發生一些異常時,就會調用FaultCallback。調用錯誤處理函數需要一組參數,這些參數包括NativeActivityFaultContext和未處理的異常。該NativeActivityFaultContext包含一個用于錯誤處理的HandleFault()函數。考慮到工作流的異步特性,最直接的一個try / catch塊是行不通。
??? 因此,我希望下面活動能捕獲任何異常,然后繼續。
?2?????{
?3?????????public?Activity?Body?{?get;?set;?}?
?4?????????protected?override?void?Execute(NativeActivityContext?context)
?5?????????{?
?6?????????????context.ScheduleActivity(Body,?FaultHandler);
?7?????????}?
?8?????????private?void?FaultHandler(NativeActivityFaultContext?faultContext,?Exception?propagatedException,?ActivityInstance?propagatedFrom)
?9?????????{
10?????????????Console.WriteLine(propagatedException.Message);
11?????????????faultContext.HandleFault();?
12?????????}
13?????}
不要使用此代碼,它有一個嚴重的錯誤!
讓我們通過執行下面的工作流測試一下這段代碼:
?2?????????{?
?3?????????????return?new?Sequence?
?4?????????????{?
?5?????????????????Activities?=
?6?????????????????{?
?7?????????????????????new?WriteLine?{?Text?=?"Start?outer?sequence."?},
?8?????????????????????new?MyActivity?
?9?????????????????????{?
10?????????????????????????Body?=?new?Sequence
11?????????????????????????{?
12?????????????????????????????Activities?=?
13?????????????????????????????{?
14????????????????????????????????new?WriteLine?{?Text?=?"Start?inner?sequence."?},
15????????????????????????????????new?Throw?
16????????????????????????????????{
17????????????????????????????????????Exception?=?new?InArgument<Exception>(ctx?=>?new?DivideByZeroException())
18????????????????????????????????},
19????????????????????????????????new?WriteLine?{?Text?=?"End?inner?sequence."?}?
20?????????????????????????????}
21?????????????????????????}
22?????????????????????},?
23??????????????????????new?WriteLine?{?Text?=?"End?outer?sequence."?}
24?????????????????}?
25?????????????};?
26?????????}
對于這個工作流,我期待下面這樣的輸出:
但實際情況是別的東西,我會收到以下輸出:
?
即使異常被上級捕獲,我們可以看到第二個內部的WriteLine仍然執行了!
這種現象讓我們想起了臭名昭著VB6 On Error Resume Next ,當某語句出現錯誤時,跳過它,執行下面一行的代碼。
這并不是我真正期待和希望的。修復很容易。所需要做的是使用CancelChild()函數明確取消正在執行的子活動。下面是NativeActivity的正確版本。
?2?????{
?3?????????public?Activity?Body?{?get;?set;?}?
?4?????????protected?override?void?Execute(NativeActivityContext?context)
?5?????????{?
?6?????????????context.ScheduleActivity(Body,?FaultHandler);
?7?????????}?
?8?????????private?void?FaultHandler(NativeActivityFaultContext?faultContext,?Exception?propagatedException,?ActivityInstance?propagatedFrom)
?9?????????{
10?????????????Console.WriteLine(propagatedException.Message);
11?????????????faultContext.HandleFault();
12?????????????faultContext.CancelChild(propagatedFrom);
13?????????}
14?????}
本文轉自麒麟博客園博客,原文鏈接:http://www.cnblogs.com/zhuqil/archive/2010/03/11/error-handling-in-a-nativeactivity.html,如需轉載請自行聯系原作者
?