Windows Workflow Foundation 例外狀況
工作流程可以利用 TryCatch 活動處理在工作流程執行期間引發的例外狀況。 工作流程可以處理這些例外狀況,也可以利用 Rethrow 活動重新擲回。 Finally 區段中的活動是在 Try 區段或 Catches 區段完成時執行的。 WorkflowApplication 執行個體所裝載的工作流程也可以利用 OnUnhandledException 事件處理常式來處理未經 TryCatch 活動處理的例外狀況。
例外狀況的原因
在工作流程中,例外狀況會發生在下列情況:
TransactionScope 中的交易逾時。
工作流程使用 Throw 活動擲回明確的例外狀況。
從活動擲回的 .NET Framework 4.6.1 例外狀況。
從外部程式碼 (例如程式庫、元件或工作流程中使用的服務) 擲回例外狀況。
例外狀況處理
如果活動擲回例外狀況,且該例外狀況未經處理,預設的行為是終止該工作流程執行個體。 如果自訂的 OnUnhandledException 處理常式存在,即可覆寫這個預設行為。 這個處理常式可讓工作流程主機作者提供適當的處理,例如自訂登入、中止工作流程、取消工作流程,或者終止工作流程。 如果工作流程引發未處理的例外狀況,則會叫用 OnUnhandledException 處理常式。 OnUnhandledException 會傳回三種可能的動作,這些動作決定工作流程最終的結果。
取消 - 取消的工作流程執行個體是分支執行的非失誤性結束。 您可以建立取消行為模型 (例如使用 CancellationScope 活動)。 取消流程完成時,將叫用 Completed 處理常式。 取消的工作流程處於 Cancelled 狀態。
終止 - 無法恢復或重新啟動已終止的工作流程執行個體。 這個動作會觸發 Completed 事件,您可在其中提供例外狀況說明終止原因。 終止流程完成時,將叫用 Terminated 處理常式。 終止的工作流程處於 Faulted 狀態。
中止 - 中止的工作流程設定為持續性後,才能繼續。 沒有持續性就不能恢復工作流程。 工作流程中止時,會失去上一個持續點以來 (在記憶體中) 完成的所有工作。 若為中止的工作流程,會在中止程序完成時使用例外狀況叫用 Aborted 處理常式說明原因。 不過,Completed 不同於 Cancelled 和 Terminated 之處在於它不會被叫用。 中止的工作流程處於 Aborted 狀態。
下列範例會叫用擲回例外狀況的工作流程。 此例外狀況未由工作流程處理,而且叫用了 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 {0}\n{1}",
e.InstanceId, e.UnhandledException.Message);
Console.WriteLine("ExceptionSource: {0} - {1}",
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 活動攔截該例外狀況,而不論該例外狀況是否由該層級較高的 TryCatch 重新擲回。
該例外狀況未經層級較高的 TryCatch 處理、溢出工作流程的根目錄,且該工作流程設定為取消而非終止或中止。 使用 WorkflowApplication 裝載的工作流程可以透過處理 OnUnhandledException 及傳回 Cancel 進行此設定。 本主題前文亦提供處理 OnUnhandledException 的範例。 工作流服務可以使用 WorkflowUnhandledExceptionBehavior 並指定 Cancel 來進行此設定。 如需設定 WorkflowUnhandledExceptionBehavior 的範例,請參閱工作流程服務主機擴充性。
例外狀況處理與補償
例外狀況處理與補償之間的不同在於,例外狀況處理會發生於活動執行期間。 補償則是發生於活動順利完成後。 例外狀況處理可讓您在活動引發例外狀況後進行清理,而補償則提供一種機制,利用這種機制即可復原先前完成之活動順利完成的工作。 如需詳細資訊,請參閱補償。