工作流程可以使用 TryCatch 活動來處理工作流程執行期間引發的例外狀況。 您可以處理這些例外狀況,或使用 Rethrow 活動重新擲回這些例外狀況。 當 Try 區段或 Catches 區段完成時,就會執行 [Finally] 區段中的活動。 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 活動具有與特定 Exception 類型相關聯的 Catch 活動 Catches 集合。 如果 TryCatch 活動 Try 區段中所包含的活動擲回的例外狀況符合 Catches 集合中 Catch<TException> 活動的例外狀況,則會處理例外狀況。 如果明確重新擲回例外狀況,或擲回新的例外狀況,則此例外狀況會傳遞至父活動。 下列程式代碼範例顯示 TryCatch 活動,此活動會處理 Throw 活動在 Try 區段中擲回的 ApplicationException。 例外狀況的訊息會由 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."
}
};
當 Try 區段或 Catches 區段順利完成時,就會執行 Finally 區段中的活動。 如果沒有任何例外狀況從中擲回,則 Try 區段會順利完成,如果沒有任何例外狀況擲回或重新擲回,則 Catches 區段會順利完成。 如果在 TryCatch 的 Try 區段中擲回例外狀況,而且不是由 Catches 區段中的 Catch<TException> 處理,或是從 Catches重新擲回 ,除非發生下列其中一項,否則不會執行 Finally 中的活動。
例外狀況不會由較高層級的 TryCatch處理,會逸出工作流程的根目錄,而且工作流程已設定為取消,而不是終止或中止。 使用 WorkflowApplication 裝載的工作流程可以藉由處理 OnUnhandledException 並傳回 Cancel來設定此設定。 本主題先前提供處理 OnUnhandledException 的範例。 工作流程服務可以使用 WorkflowUnhandledExceptionBehavior 並指定 Cancel來設定此設定。 如需設定 WorkflowUnhandledExceptionBehavior的範例,請參閱 Workflow Service Host Extensibility。
例外狀況處理與補償
例外狀況處理和補償之間的差異在於,例外狀況處理會在活動執行期間發生。 補償會在活動成功完成之後發生。 例外狀況處理提供在活動引發例外狀況之後清除的機會,而補償則提供機制,讓先前完成活動的成功完成工作可以復原。 如需詳細資訊,請參閱 補償。