例外

このトピックの内容は、Windows Workflow Foundation 4 に該当します。

ワークフローは、TryCatch アクティビティを使用して、ワークフローの実行中に発生した例外を処理することができます。これらの例外は、処理することも可能ですが、Rethrow アクティビティを使用して再スローすることもできます。Finally セクションのアクティビティは、Try セクションまたは Catches セクションが完了したときに実行されます。また、WorkflowApplication インスタンスによってホストされるワークフローは OnUnhandledException イベント ハンドラーを使用して、TryCatch アクティビティで処理されない例外を処理することができます。

例外の原因

ワークフローでは、例外は、次の方法で生成されます。

  • TransactionScope でのトランザクションのタイムアウト

  • Throw アクティビティを使用してワークフローからスローされた明示的な例外

  • アクティビティからスローされた .NET Framework 4 例外

  • ワークフローで使用されているライブラリ、コンポーネント、サービスなどの外部コードからスローされた例外

例外処理

アクティビティからスローされた例外が処理されない場合、既定の動作では、ワークフロー インスタンスが終了します。カスタムの OnUnhandledException ハンドラーが存在する場合、このハンドラーで既定の動作をオーバーライドできます。このハンドラーがあると、ワークフロー ホストの作成者は、カスタムのログ記録、ワークフローの中止、ワークフローのキャンセル、ワークフローの終了などの適切な処理を実行できます。次の例は、例外をスローするワークフローを呼び出します。ワークフローで例外が処理されないため、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 アクティビティには、それぞれが特定の Exception 型に関連付けられている Catch アクティビティの Catches コレクションがあります。TryCatch アクティビティの Try セクションに含まれているアクティビティからスローされた例外が、Catches コレクションの Catch アクティビティの例外に一致する場合、スローされた例外が処理されます。例外が明示的に再スローされるか、新しい例外がスローされた場合、この例外は親アクティビティに渡されます。Finally セクションのアクティビティは、Try セクションまたは Catches セクションが正常に完了したときに実行されます。次のコード例は、Try セクションで Throw アクティビティからスローされた ApplicationException を処理する TryCatch アクティビティを示しています。例外のメッセージが Catch アクティビティによってコンソールに書き込まれた後、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."
    }
};

例外処理と補正の比較

例外処理は、アクティビティの実行中に発生するという点で補正と異なります。補正が発生するのは、アクティビティが正常に完了した後です。例外処理では、アクティビティが例外を生成した後でクリーン アップを実行できます。また、補正処理では、前に完了したアクティビティの正常に完了した作業を元に戻すことが可能です。詳細については、次のトピックを参照してください。 Compensation Programming Model.

参照

リファレンス

TryCatch
OnUnhandledException
CompensableActivity