共用方式為


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 區段中擲回的 ThrowCatch<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 區段也會順利完成。 如果 TryTryCatch 區段擲回例外狀況,且未經 Catch<TException> 區段中的 Catches 處理,或由 Catches 重新擲回,則不會執行 Finally 中的活動,除非發生下列其中任一情況。

例外狀況處理與補償

例外狀況處理與補償之間的不同在於,例外狀況處理會發生於活動執行期間。 補償則是發生於活動順利完成後。 例外狀況處理可讓您在活動引發例外狀況後進行清理,而補償則提供一種機制,利用這種機制即可復原先前完成之活動順利完成的工作。 如需詳細資訊,請參閱補償

另請參閱