工作流程可以使用 TryCatch 活動來處理工作流程執行期間引發的例外狀況。 您可以處理這些例外狀況,或使用 Rethrow 活動重新擲回這些例外狀況。 當 Finally 區段或 Try 區段完成時,就會執行 [Catches] 區段中的活動。 WorkflowApplication 實例所裝載的工作流程也可以使用 OnUnhandledException 事件處理程式來處理 TryCatch 活動未處理的例外狀況。
例外狀況的原因
在工作流程中,可以透過下列方式產生例外狀況:
TransactionScope的交易逾時。
工作流程使用 Throw 活動擲回的明確例外狀況。
從活動擲回的 .NET Framework 4.6.1 例外狀況。
從外部程式代碼擲回的例外狀況,例如工作流程中使用的連結庫、元件或服務。
處理例外狀況
如果活動擲回例外狀況且未處理,則預設行為是終止工作流程實例。 如果自定義 OnUnhandledException 處理程式存在,它可以覆寫此預設行為。 此處理程式可讓工作流程主機作者有機會提供適當的處理,例如自定義記錄、中止工作流程、取消工作流程或終止工作流程。 如果工作流程引發未處理的例外狀況,則會叫用 OnUnhandledException 處理程式。 從 OnUnhandledException 傳回的可能動作有三個,可決定工作流程的最終結果。
取消 - 取消的工作流程實例是分支執行正常結束。 您可以建立取消行為模型(例如,使用 CancellationScope 活動)。 取消程式完成時,會叫用 Completed 處理程式。 已取消的工作流程處於 [已取消] 狀態。
終止 - 無法繼續或重新啟動終止的工作流程實例。 這會觸發 Completed 事件,您可以在其中提供例外狀況作為終止原因。 終止處理程式完成時,會叫用終止處理程式。 終止的工作流程處於錯誤狀態。
中止 - 只有在已設定為持續性的工作流程實例時,才能繼續中止的工作流程實例。 如果沒有持續性,就無法繼續工作流程。 在工作流程中止時,因為最後一個持續性點將會遺失任何已完成的工作(記憶體中)。 對於中止的工作流程,會使用例外狀況叫用中止處理程式,做為中止進程完成的原因。 不過,與 Cancelled 和 Terminated 不同,不會叫用 Completed 處理程式。 中止的工作流程處於中止狀態。
下列範例會叫用擲回例外狀況的工作流程。 工作流程未處理例外狀況,並叫用 OnUnhandledException 處理程式。 系統會檢查 WorkflowApplicationUnhandledExceptionEventArgs 以提供例外狀況的相關信息,並終止工作流程。
Activity wf = new Sequence
{
Activities =
{
new WriteLine
{
Text = "Starting the workflow."
},
new Throw
{
Exception = new InArgument<Exception>((env) =>
new ApplicationException("Something unexpected happened."))
},
new WriteLine
{
Text = "Ending the workflow."
}
}
};
WorkflowApplication wfApp = new WorkflowApplication(wf);
wfApp.OnUnhandledException = delegate (WorkflowApplicationUnhandledExceptionEventArgs e)
{
// Display the unhandled exception.
Console.WriteLine($"OnUnhandledException in Workflow {e.InstanceId}\n{e.UnhandledException.Message}");
Console.WriteLine($"ExceptionSource: {e.ExceptionSource.DisplayName} - {e.ExceptionSourceInstanceId}");
// Instruct the runtime to terminate the workflow.
return UnhandledExceptionAction.Terminate;
// Other choices are UnhandledExceptionAction.Abort and
// UnhandledExceptionAction.Cancel
};
wfApp.Run();
使用 TryCatch 活動處理例外狀況
使用 TryCatch 活動執行工作流程內的例外狀況。 TryCatch 活動具有與特定 Catches 類型相關聯的 Catch 活動 Exception 集合。 如果 Try 活動 TryCatch 區段中所包含的活動擲回的例外狀況符合 Catch<TException> 集合中 Catches 活動的例外狀況,則會處理例外狀況。 如果明確重新擲回例外狀況,或擲回新的例外狀況,則此例外狀況會傳遞至父活動。 下列程式代碼範例顯示 TryCatch 活動,此活動會處理 ApplicationException 活動在 Try 區段中擲回的 Throw。 例外狀況的訊息會由 Catch<TException> 活動寫入主控台,然後在 [Finally] 區段中將訊息寫入控制台。
DelegateInArgument<ApplicationException> ex = new DelegateInArgument<ApplicationException>()
{
Name = "ex"
};
Activity wf = new TryCatch
{
Try = new Throw()
{
Exception = new InArgument<Exception>((env) => new ApplicationException("An ApplicationException was thrown."))
},
Catches =
{
new Catch<ApplicationException>
{
Action = new ActivityAction<ApplicationException>
{
Argument = ex,
Handler = new WriteLine()
{
Text = new InArgument<string>((env) => ex.Get(env).Message)
}
}
}
},
Finally = new WriteLine()
{
Text = "Executing in Finally."
}
};
當 Finally 區段或 Try 區段順利完成時,就會執行 Catches 區段中的活動。 如果沒有任何例外狀況從中擲回,則 Try 區段會順利完成,如果沒有任何例外狀況擲回或重新擲回,則 Catches 區段會順利完成。 如果在 Try 的 TryCatch 區段中擲回例外狀況,而且不是由 Catch<TException> 區段中的 Catches 處理,或是從 Catches重新擲回 ,除非發生下列其中一項,否則不會執行 Finally 中的活動。
例外狀況不會由較高層級的 TryCatch處理,會逸出工作流程的根目錄,而且工作流程已設定為取消,而不是終止或中止。 使用 WorkflowApplication 裝載的工作流程可以藉由處理 OnUnhandledException 並傳回 Cancel來設定此設定。 本主題先前提供處理 OnUnhandledException 的範例。 工作流程服務可以使用 WorkflowUnhandledExceptionBehavior 並指定 Cancel來設定此設定。 如需設定 WorkflowUnhandledExceptionBehavior的範例,請參閱 Workflow Service Host Extensibility。
例外狀況處理與補償
例外狀況處理和補償之間的差異在於,例外狀況處理會在活動執行期間發生。 補償會在活動成功完成之後發生。 例外狀況處理提供在活動引發例外狀況之後清除的機會,而補償則提供機制,讓先前完成活動的成功完成工作可以復原。 如需詳細資訊,請參閱 補償。