共用方式為


Windows Workflow Foundation 例外狀況

工作流程可以使用 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 區段會順利完成。 如果在 TryCatchTry 區段中擲回例外狀況,而且不是由 Catches 區段中的 Catch<TException> 處理,或是從 Catches重新擲回 ,除非發生下列其中一項,否則不會執行 Finally 中的活動。

例外狀況處理與補償

例外狀況處理和補償之間的差異在於,例外狀況處理會在活動執行期間發生。 補償會在活動成功完成之後發生。 例外狀況處理提供在活動引發例外狀況之後清除的機會,而補償則提供機制,讓先前完成活動的成功完成工作可以復原。 如需詳細資訊,請參閱 補償

另請參閱