다음을 통해 공유


Windows Workflow Foundation 예외

워크플로에서 TryCatch 활동을 사용하여 워크플로 실행 중에 발생하는 예외를 처리할 수 있습니다. 이러한 예외를 처리하거나 Rethrow 활동을 사용하여 다시 throw할 수 있습니다. Finally 섹션의 활동은 Try 섹션 또는 Catches 섹션이 완료되면 실행됩니다. WorkflowApplication 인스턴스에 의해 호스트된 워크플로에서는 OnUnhandledException 이벤트 처리기를 사용하여 TryCatch 활동에서 처리되지 않은 예외를 처리할 수 있습니다.

예외의 원인

워크플로에서 다음과 같은 방식으로 예외가 생성될 수 있습니다.

  • TransactionScope에서 트랜잭션의 시간 초과

  • Throw 활동을 사용하여 워크플로에서 throw된 명시적 예외.

  • 활동에서 throw되는 .NET Framework 4.6.1 예외입니다.

  • 워크플로에서 사용되는 라이브러리, 구성 요소 또는 서비스와 같은 외부 코드에서 throw되는 예외

예외 처리

활동에서 예외가 throw되었지만 처리되지 않은 경우 워크플로 인스턴스를 종료하는 것이 기본 동작입니다. 사용자 지정 OnUnhandledException 처리기가 있는 경우 이 기본 동작을 재정의할 수 있습니다. 워크플로 호스트 작성자는 이 처리기를 사용하여 사용자 지정 로깅, 워크플로 중단, 워크플로 취소, 워크플로 종료 등의 적절한 처리를 제공할 수 있습니다. 처리할 수 없는 예외가 워크플로에 발생한 경우 OnUnhandledException 처리기가 호출됩니다. 워크플로의 최종 결과를 결정하는 OnUnhandledException에서 반환된 가능한 동작에는 3가지가 있습니다.

  • 취소 - 분기 실행의 정상적인 방식으로 종료하는 취소된 워크플로 인스턴스입니다. 취소 동작은 CancellationScope 활동을 사용하는 경우와 같이 모델링할 수 있습니다. 완료된 처리기는 취소 프로세스가 완료되면 호출됩니다. 취소된 워크플로는 Cancelled 상태입니다.

  • 종료 - 종료된 워크플로 인스턴스는 재개 또는 다시 시작할 수 없습니다. 이 실행에서는 종료된 이유로서 예외를 제공할 수 있는 완료된 이벤트를 트리거합니다. 종료된 처리기는 종료 프로세스가 완료되면 호출됩니다. 종료된 워크플로는 Faulted 상태입니다.

  • 중단 - 중단된 워크플로 인스턴스는 영구적으로 구성된 경우에만 재개할 수 있습니다. 지속성이 없을 경우 워크플로는 재개할 수 없습니다. 이렇게 하면 워크플로가 중단된 경우 마지막 유지 시점 이후의 모든 작업 수행(메모리)이 손실됩니다. 중단된 워크플로의 경우 중단 프로세스가 완료된 이유로서 중단된 처리기가 예외를 통해 호출됩니다. 그러나, Cancelled 및 Terminated와 같이 Completed 처리기는 호출되지 않습니다. 중단된 워크플로가 중단된 상태인 경우입니다.

다음 예제에서는 예외를 throw하는 워크플로를 호출합니다. 이 예외는 워크플로에서 처리되지 않으며 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 섹션에 포함된 활동에 의해 throw된 예외가 Catch<TException> 컬렉션의 Catches 활동의 예외와 일치하면 예외가 처리됩니다. 예외가 명시적으로 다시 throw되거나 새 예외가 throw될 경우 이 예외는 부모 활동에 전달됩니다. 다음 코드 예제에서는 TryCatch 섹션에서 ApplicationException 활동에 의해 throw되는 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 단원은 예외가 throw되면 성공적으로 완료되고 예외가 throw되거나 다시 throw되지 않으면 Catches 단원이 성공적으로 완료됩니다. 예외가 TryTryCatch 단원에서 throw되고 Catch<TException> 단원에서 Catches에 의해 처리되지 않거나 Catches에서 다시 throw되면 Finally의 모든 활동은 다음 중 하나가 발생하지 않는 한 실행되지 않습니다.

예외 처리와 보정 비교

예외 처리와 보정의 차이점은 예외 처리는 활동 실행 중에 발생하고, 보정은 활동이 완료된 이후에 발생한다는 점입니다. 예외 처리를 사용하면 활동에서 예외가 발생한 이후에 정리 작업이 가능하고, 보정을 사용하면 이전에 성공적으로 완료된 활동을 실행 취소할 수 있습니다. 자세한 내용은 보정을 참조하세요.

참고 항목