Windows Workflow Foundation 호스팅에 대한 소개

2007. 1. 14. 19:05 IT 및 개발/.NET FX & Visual C#

요약: Windows WF(Workflow Foundation)를 호스팅하는 응용 프로그램이 실행 중인 워크플로를 관리 및 모니터링하는 방법과 런타임 서비스 및 기본 구현 방법에 대한 개요를 제공합니다. 이 기사는 Microsoft .NET Framework, C# 및 WF 프로그래밍 모델에 대한 지식이 있는 사용자를 대상으로 합니다.

소개

이 기사는 Windows WF(Workflow Foundation)를 사용하는 개발자가 실행 중인 워크플로 인스턴스를 관리 및 모니터링하는 데 사용할 수 있는 응용 프로그램의 다양한 옵션을 쉽게 이해하도록 돕기 위한 것입니다. 따라서 이 기사는 독자가 Microsoft .NET Framework, C# 및 WF에 대한 기본 지식이 있다는 가정 하에 작성되었습니다.

WF는 작업 라이브러리 및 프레임워크, 런타임 엔진 및 런타임 서비스 구성 요소로 구성되어 있으며, 이러한 구성 요소는 호스트 응용 프로그램 프로세스 내에서 실행되어야 합니다. 워크플로는 런타임 엔진에서 실행하는 일련의 작업으로 구성되어 있으며, 런타임 엔진은 호스트 응용 프로그램 프로세스 내에서 실행되어야 합니다. 다음 그림에서는 워크플로, 작업 및 워크플로 런타임 엔진을 호스트 응용 프로그램 프로세스에서 호스팅하는 방법을 보여 줍니다.


그림 1. Windows Workflow Foundation 호스트 프로세스

WF는 워크플로 실행 및 상태 관리를 담당하는 런타임 엔진을 제공합니다. WF 런타임은 ASP.NET, Windows 서비스, 콘솔 응용 프로그램 및 Windows Forms 응용 프로그램을 포함한 모든 .NET 프로세스에서 호스팅할 수 있습니다. 워크플로를 사용하는 응용 프로그램을 빌드할 때 개발자가 이러한 호스트 프로세스를 작성해야 합니다. 런타임 서비스는 호스트 프로세스에서 실행되어 런타임 엔진이 워크플로 실행을 관리할 때 런타임 엔진에 추가 기능을 제공합니다.

호스트 응용 프로그램을 WF에 맞게 구현할 경우 여러 가지 사항을 고려해야 합니다. 이 기사에서는 호스트 응용 프로그램이 워크플로를 관리 및 모니터링하는 방법에 대한 개요를 제공하며 기본 런타임 서비스 및 기본 구현 방법에 대해 간략하게 설명합니다.


워크플로 인스턴스 수명 주기 관리

WF는 WorkflowInstance 클래스에서 기본 작업 및 제어 작업 메서드를 제공하여 워크플로 상태 및 수명 주기를 관리합니다. 워크플로 인스턴스 수명 주기 관리 섹션에서는 다양한 워크플로 인스턴스 관련 런타임 이벤트, 이러한 이벤트 간의 전환 및 워크플로 상태 관계에 대해 설명합니다.

보존 지점

워크플로가 장시간 실행되는 빈도가 많아져서 사실상 유휴 시간이 길어지면 사용자나 다른 시스템이 입력 작업에 대해 대기하는 시간이 길어집니다. 메모리에 유휴 워크플로를 두는 것은 실용적이지 못하므로 워크플로가 대기 중인 이벤트를 수신할 때까지 워크플로 인스턴스 상태를 저장 매체에 보존하는 것이 좋습니다. 또한 워크플로 인스턴스 상태를 저장해 두면 이후 프로세스에서 오류가 발생할 경우 저장했던 지점부터 워크플로를 다시 시작할 수 있습니다.

그림 2에서는 보존 지점을 사용하여 실행 중인 워크플로 인스턴스를 다시 시작하는 방법을 보여 줍니다.


그림 2. 보존 지점을 사용하여 실행 중인 워크플로 인스턴스 다시 시작

워크플로 인스턴스 상태가 B 지점에서 보존되고 C 지점에서 오류가 발생한 경우 A 지점과 B 지점 사이에 완료된 작업이 손실되지 않고 워크플로 인스턴스를 B 지점부터 다시 시작할 수 있습니다. 하지만 보존 서비스를 사용할 수 없거나 워크플로 인스턴스 상태가 보존되지 않은 경우에는 A 지점과 B 지점 사이에 완료된 작업을 잃게 됩니다.

WorkflowPersistenceService가 있는 경우 즉, WorkflowRuntime 인스턴스에 추가된 경우 워크플로 런타임 엔진이 이 서비스를 사용하여 워크플로 인스턴스 상태를 저장 매체에 보존합니다. 이러한 작업은 다음 지점에서 수행될 수 있습니다.

  • PersistOnCloseAttribute로 표시된 작업 완료 시(예: 트랜잭션 범위 작업)
  • 워크플로 인스턴스 완료 전
  • 워크플로 인스턴스 종료 전
  • 워크플로가 유휴 상태로 되는 경우
  • WorkflowInstance.Unload 또는 WorkflowInstance.TryUnload가 호출된 경우

WF 런타임 엔진은 WorkflowPersistenceService에서 SaveWorkflowInstanceState() 메서드를 호출하여 워크플로 인스턴스 상태를 저장하며 필요한 경우 LoadWorkflowInstanceState() 메서드를 호출하여 워크플로 인스턴스 보존 상태를 검색합니다. 워크플로 런타임은 보존 수행 시기에 관한 모든 구문을 처리하고, 보존 서비스는 워크플로 인스턴스에 대한 실제 저장 및 로드를 담당하며, 작업 상태 및 워크플로 인스턴스 ID는 직렬화되어 보존 저장소에 저장됩니다. 또한 워크플로 인스턴스 실행을 다시 시작하는 데 필요한 다른 모든 정보(예: 대기열)도 직렬화되어 저장됩니다.

워크플로 인스턴스 이벤트

워크플로 인스턴스의 상태는 5가지, 즉 Created, Running, Suspended, Completed, Terminated 중 하나가 될 수 있습니다. 워크플로 인스턴스가 실행되는 동안 워크플로에는 13개의 이벤트가 발생할 수 있는데, 이러한 이벤트는 다른 상태로의 전환을 나타낼 수 있습니다. 예를 들어 WorkflowCompleted 이벤트는 인스턴스가 Running 상태에서 Completed 상태로 전환되었음을 나타냅니다. 일부 이벤트는 인스턴스가 다른 상태로 전환되었음을 나타내지 않기도 합니다. 예를 들어 WorkflowPersisted 이벤트는 인스턴스가 Persisted 상태이지만 여전히 Running 상태임을 나타냅니다. 13개의 이벤트 중 11개는 런타임 이벤트 및 워크플로 추적 이벤트를 통해 호스트 응용 프로그램과 통신하지만 Changed 이벤트와 Exception 이벤트는 워크플로 추적 이벤트를 통해서만 호스트 응용 프로그램과 통신할 수 있습니다.

호스트 응용 프로그램은 WF가 WorkflowInstance 클래스에 제공하는 제어 작업 메서드를 사용하여 워크플로 수명 주기를 관리할 수 있습니다. 또한 워크플로 수명 주기는 정책 설정을 통해서도 관리할 수 있습니다. 예를 들어 응용 프로그램은 언로드 정책을 사용하여 WF 엔진이 워크플로 인스턴스를 언로드하도록 지시할 수 있습니다. WF는 워크플로 인스턴스 상태에 영향을 줄 수 있는 기본 작업을 제공합니다. 예를 들어 SuspendActivityTerminateActivity 작업을 사용하여 워크플로 인스턴스를 각각 일시 중단하거나 종료할 수 있습니다. 다음 섹션에서는 워크플로 인스턴스의 상태 전환 및 워크플로 인스턴스 이벤트와 통신하기 위해 워크플로 런타임이 발생시키는 다양한 워크플로 인스턴스 관련 이벤트에 대해 설명합니다.

WorkflowAborted

워크플로 런타임 엔진이 메모리 내 인스턴스를 제거하면 워크플로 인스턴스가 중단됩니다. 호스트 응용 프로그램은 WorkflowInstance.Abort()를 호출하여 워크플로 인스턴스를 중단할 수 있습니다. 중단된 워크플로 인스턴스는 WorkflowInstance.Resume()을 호출하여 마지막 보존 지점부터 다시 시작할 수 있습니다. 워크플로 인스턴스 중단은 응용 프로그램이 마지막 보존 지점부터 WorkflowInstance.Abort()가 호출되기 직전까지 완료된 모든 작업을 취소하기로 결정하는 경우처럼 극단적인 상황에 사용됩니다.

WorkflowCompleted

워크플로 인스턴스가 실행을 끝마치면 해당 인스턴스가 완료됩니다. 이때 호스트 응용 프로그램은 워크플로 인스턴스가 소비하지 않은 다른 이벤트 및 메시지 대기열을 검사할 수 있습니다.

WorkflowCreated

워크플로는 인스턴스 생성을 마친 후 작업 실행이 시작되기 전에 생성됩니다. 워크플로 인스턴스는 여러 개의 오버로드된 WorkflowRuntime.CreateWorkflow() 메서드 중 하나를 호출하여 생성할 수 있습니다.

WorkflowIdled

외부 이벤트(예: 타이머, 메시지 또는 기타 사용자 지정 이벤트)가 실행되는 동안 기다릴 때 워크플로 인스턴스는 유휴 상태가 됩니다. 시스템 리소스를 절약하기 위해 응용 프로그램은 언로드 정책을 설정하여 유휴 상태인 워크플로 인스턴스를 메모리에서 언로드할 수 있습니다. 호스트 응용 프로그램이 기본 SqlWorkflowPersistenceService를 사용하는 경우 응용 프로그램 구성 파일에 UnloadOnIdle 플래그를 설정하여 인스턴스가 유휴 상태일 때 WF 런타임 엔진이 워크플로 상태를 보존하도록 지시할 수 있습니다.

WorkflowLoaded

인스턴스 상태를 보존 저장소에서 메모리로 로드하는 경우 WorkflowLoaded 이벤트가 발생합니다.

WorkflowPersisted

WorkflowRuntime 인스턴스에 기본 SqlWorkflowPersistenceService 또는 사용자 지정 보존 서비스가 추가된 경우 워크플로 인스턴스 상태를 보존 저장소에 저장하면 워크플로 인스턴스가 보존됩니다.

WorkflowResumed

중단 또는 일시 중단된 워크플로 인스턴스에서 WorkflowInstance.Resume()을 호출하면 해당 워크플로 인스턴스가 다시 시작됩니다.

WorkflowStarted

WorkflowInstance.Start()를 호출하면 WorkflowStarted 이벤트가 발생합니다. WorkflowStarted 이벤트는 워크플로 런타임 엔진이 워크플로 작업을 실행하기 전에 발생합니다.

WorkflowSuspended

WorkflowInstance.Suspend()를 호출하거나 SuspendActivity 작업을 실행하면 워크플로 인스턴스가 일시 중단됩니다. 그 결과 워크플로 인스턴스는 일시 중단 상태가 됩니다.

WorkflowTerminated

WorkflowInstance.Terminate()를 호출하거나, TerminateActivity 작업을 실행하거나, 실행 중인 워크플로 인스턴스에서 처리되지 않는 예외가 발생하면 워크플로 인스턴스가 종료됩니다. 이 이벤트가 발생하면 워크플로 인스턴스는 종료 상태가 됩니다.

WorkflowUnloaded

워크플로 인스턴스가 메모리에서 보존 저장소로 언로드되는 경우 WorkflowUnloaded 이벤트가 발생하며, 이는 보존 정책에 따라 수행되거나 WorkflowInstance.Unload() 또는 WorkflowInstance.TryUnload() 호출을 통해 수행됩니다.

워크플로 인스턴스 이벤트 전환

워크플로 인스턴스 이벤트는 워크플로 런타임 이벤트와 워크플로 추적 이벤트를 통해 호스트와 통신합니다. 호스트 응용 프로그램은 런타임 이벤트를 구독하거나 추적 서비스를 사용하여 알림을 수신할 수 있습니다. Exception 및 Changed 이벤트는 추적 서비스를 통해서만 호스트 응용 프로그램과 통신합니다. Exception 이벤트는 워크플로 인스턴스 실행 중에 예외가 발생했음을 나타내며 Changed 이벤트는 실행 중에 워크플로 인스턴스가 동적으로 업데이트되었음을 나타냅니다.

그림 3에서는 다양한 워크플로 이벤트 간의 전환과 워크플로 상태를 보여 줍니다.

사용자 삽입 이미지

그림 3. 워크플로 이벤트 간 전환 및 상태(더 큰 이미지를 보려면 이미지를 클릭하십시오.)

보존 서비스를 사용할 수 있다면 그림 3에 나타나 있듯이 보존 지점이 생성됩니다. WorkflowPersisted, WorkflowUnloadedWorkflowLoaded 이벤트를 사용할 수 있는 경우 호스트 응용 프로그램이 이러한 이벤트를 확인할 수 있어야 합니다. 워크플로 인스턴스가 메모리에 없을 때 보존 서비스를 사용하면 워크플로 인스턴스가 먼저 로드된 후 인스턴스에서 유효한 작업(Resume, Abort, Terminate 등)이 수행됩니다. 예를 들어, 워크플로 인스턴스가 일시 중단된 채 언로드된 경우 Resume을 호출하면 다이어그램에 나타나 있듯이 워크플로 인스턴스가 먼저 로드된 후 Resumed 이벤트가 발생합니다.

워크플로 인스턴스 작업

앞에서도 설명했듯이 WorkflowInstance 클래스는 워크플로 인스턴스의 수명 주기를 제어하기 위해 메서드를 사용합니다. 이 섹션에서는 이러한 메서드에 대해 설명합니다.

WorkflowInstance.Start()

생성된 워크플로 인스턴스를 실행합니다. WorkflowInstance.Start()가 실행되면 워크플로 런타임이 WorkflowStarted 이벤트를 발생시키며 워크플로 인스턴스는 Running 상태가 됩니다. 이미 시작된 워크플로 인스턴스에 대해 Start()를 호출하면 InvalidOperationException이 발생합니다.

WorkflowInstance.Abort()

워크플로 인스턴스를 중단합니다. 성공적으로 중단되면 워크플로 런타임이 WorkflowAborted 이벤트를 발생시킵니다.

WorkflowInstance.Load()

언로드된 워크플로 인스턴스를 보존 저장소에서 메모리로 로드합니다. 그 다음 이 인스턴스는 언로드되기 전에 있었던 상태부터 실행됩니다. 성공적으로 로드되면 워크플로 런타임이 WorkflowLoaded 이벤트를 발생시킵니다.

WorkflowInstance.Resume()

중단 또는 일시 중단된 워크플로 인스턴스를 다시 시작하고 실행합니다. 워크플로 런타임은 워크플로 인스턴스 실행이 다시 시작되기 바로 전에 WorkflowResumed 이벤트를 발생시킵니다.

WorkflowInstance.Suspend()

워크플로 인스턴스 실행을 일시 중단합니다. WorkflowInstance.Suspend()를 성공적으로 호출하면 워크플로 런타임이 WorkflowSuspended 이벤트를 발생시킵니다.

WorkflowInstance.Terminate()

워크플로 인스턴스를 종료하고 메모리 내 워크플로 인스턴스를 지웁니다. 워크플로 런타임은 워크플로 인스턴스가 메모리에서 지워졌음을 등록된 보존 서비스에 알립니다. SqlWorkflowPersistenceService의 경우 종료 시에 해당 워크플로 인스턴스에 대한 모든 상태 정보가 데이터베이스에서 삭제되므로 이전에 저장한 보존 지점부터 워크플로 인스턴스를 다시 로드할 수 없습니다. WorkflowInstance.Terminate()에 성공하면 워크플로 런타임이 WorkflowTerminated 이벤트를 발생시킵니다.

WorkflowInstance.Unload()

워크플로 인스턴스를 메모리에서 보존 저장소로 언로드합니다. WorkflowInstance.Unload()는 동기식이므로 현재 예약된 작업을 끝마칠 때까지 또는 트랜잭션 범위의 끝부분에 도달할 때까지 다른 작업을 차단하여 언로드 작업이 성공적으로 수행될 수 있도록 합니다. WorkflowInstance.Unload()에 성공하면 워크플로 런타임이 WorkflowUnloaded 이벤트를 발생시킵니다. 등록된 보존 서비스가 없는 경우 Unload()를 호출하면 InvalidOperationException이 발생합니다.

WorkflowInstance.TryUnload()

WorkflowInstance.TryUnload()WorkflowInstance.Unload()와 달리 워크플로가 언로드될 때까지 다른 작업을 차단하지 않습니다. WorkflowInstance.TryUnload()는 워크플로 인스턴스를 메모리에서 보존 저장소로 언로드하며 인스턴스가 일시 중단 또는 유휴 상태인 경우 true를 반환하고 그렇지 않은 경우에는 false를 반환합니다. 등록된 보존 서비스가 없는 경우 TryUnload()를 호출하면 InvalidOperationException이 발생합니다.

WorkflowInstance의 다양한 제어 메서드에 대한 자세한 내용은 Windows Foundation SDK를 참조하십시오.


관리 효율 및 모니터링

워크플로를 호스팅하는 응용 프로그램은 호스팅되어 실행되는 워크플로를 관리 및 모니터링해야 합니다. WF에서는 다양한 관리 효율 및 모니터링 도구를 지원합니다. 예를 들어 WF에서는 하위 수준 디버깅에 사용할 수 있는 종단 간 추적 기능과 워크플로 데이터 추출 및 모니터링을 위한 추적 인프라를 제공합니다.

이 섹션에서는 관리 효율 및 모니터링 인프라 그리고 호스트 응용 프로그램에서 이를 사용하는 방법에 대해 설명합니다.

추적

WF에서는 워크플로 인스턴스가 실행되는 동안 워크플로, 작업 및 사용자 이벤트와 데이터를 캡처하기 위한 추적 인프라를 제공합니다. 모든 워크플로 런타임 인스턴스가 등록된 추적 서비스를 여러 개 사용하거나 전혀 사용하지 않을 수 있습니다. 추적 정보는 등록된 추적 서비스로 전송되며 호스트 응용 프로그램의 요구에 따라 추적 서비스가 이 정보를 저장 및 처리합니다. 또한 WF에서는 호스트 응용 프로그램이 사용할 수 있는 기본 SQL 기반 추적 서비스(SqlTrackingService)를 제공하며, 호스트 응용 프로그램 개발자가 자체적으로 사용자 지정 추적 서비스를 작성하여 호스트 응용 프로그램에 사용할 수도 있습니다.

추적 기능을 사용하여 워크플로 인스턴스의 실행 기록을 검사할 수 있으며 사용자 시스템에서 실행 중인 워크플로 인스턴스의 현재 상태를 확인할 수 있습니다. 또한 추적 기능을 사용하면 함께 사용 가능한 정보를 워크플로 정의에 제공하여 시스템에서 실행 중인 워크플로 인스턴스의 향후 예상 실행 경로를 예측할 수 있습니다. WF에서 제공하는 응용 프로그램 샘플(Workflow Monitor Sample)은 기본 SqlTrackingService를 사용하며 워크플로 디자이너는 현재 실행 중인 워크플로와 완료된 워크플로에 대한 워크플로 및 작업 상태 정보가 표시되도록 이 샘플을 제어합니다.

추적 기능을 사용한 워크플로 모니터링에 대한 자세한 내용은 Applications Samples/Workflow Monitor Sample의 Workflow Monitor SDK Tool 섹션을 참조하십시오. 사용자 지정 추적 서비스를 빌드하는 방법에 대한 예제를 보려면 Technology Samples/Tracking의 ConsoleTrackingService Sample 및 File Tracking Service and Query Sample 섹션을 참조하십시오. 기본 SqlTrackingService를 사용하는 방법에 대한 예제를 보려면 Technology Samples/Tracking out-of-box의 Simple Tracking Sample 및 Query Using SQLTracking Service Sample 섹션을 참조하십시오.

추적 및 종단 간 추적

추적 기능을 사용하면 응용 프로그램 상태를 모니터링한 후 실행 중인 시스템을 방해하지 않고 문제를 분리하여 수정할 수 있습니다. WF는 System.Diagnostics API를 사용하여 워크플로 런타임 및 워크플로 인스턴스 실행에 대한 정보를 추적합니다(규칙 집합 평가 정보 포함). 기본적으로 추적은 OFF로 설정되어 있지만 원하는 경우 ON으로 전환할 수 있습니다.

WF는 종단 간 추적에도 참여합니다. 종단 간 추적 기능을 사용하면 추적 뷰어에서 다양한 구성 요소 간의 연속 추적 정보 및 이러한 구성 요소 간의 전환 상태를 확인할 수 있습니다. 따라서 종단 간 디버깅이 수월해집니다.

응용 프로그램 구성 파일을 사용하는 경우 다음 구문을 추가하면 여러 WF 네임스페이스에 대한 추적을 로깅할 수 있습니다.

<system.diagnostics>
    <switches>
        <add name="System.Workflow LogToTraceListeners" value="1" />
        <add name="System.Workflow.Runtime" value="All" />
        <add name="System.Workflow.Runtime.Hosting" value="All" />
        <add name="System.Workflow.Runtime.Tracking" value="All" />
        <add name="System.Workflow.Activities" value="All" />
        <add name="System.Workflow.Activities.Rules" value="All" />
    </switches>
</system.diagnostics>

LogToTraceListeners가 사용되는 경우 WF는 호스트 응용 프로그램에서 만든 각 TraceListener를 열거하며 모든 로깅 정보를 여기에 전송합니다. 예제의 나머지 행에서는 네임스페이스를 지정하여 로깅 정보 및 추적된 정보의 양을 캡처할 수 있습니다. 값 특성에는 All, Off, Critical, Error, Warning, Information 및 Verbose를 사용할 수 있습니다. 값 특성 사용에 대한 자세한 내용은 WF SDK를 참조하십시오.

워크플로 런타임 이벤트

런타임 이벤트는 워크플로 런타임에 의해 발생되며, 워크플로 런타임 및 워크플로 인스턴스의 수명 주기를 관리하기 위한 수단을 호스트 응용 프로그램에 제공합니다. 이벤트 처리기는 WorkflowRuntime 클래스에 정의되므로 이를 사용하려면 호스트 응용 프로그램이 이러한 이벤트를 구독해야 합니다.

런타임 이벤트는 호스트 응용 프로그램이 쿼리를 위해 이벤트 및 관련 데이터를 저장하는 대신 특정 이벤트에 대해 영향을 줄 필요가 있을 때 간단한 알림 시스템의 역할을 합니다. 전자의 경우에는 추적 인프라를 사용하는 것이 좋습니다.

WorkflowRuntime 인스턴스는 여러 개의 워크플로 인스턴스를 실행할 수 있으며, 각 워크플로 인스턴스는 자체 수명 주기를 가집니다. 따라서 워크플로 인스턴스 이벤트의 이벤트 인수에는 워크플로 인스턴스 ID 및 다른 정보가 포함됩니다. 이 정보를 사용하면 해당 이벤트와 워크플로 런타임이 이 이벤트를 발생시키게 하는 워크플로 인스턴스를 연결할 수 있습니다.

다음 섹션에서는 사용 가능한 워크플로 런타임 이벤트에 대해 설명합니다.

WorkflowRuntime.ServiceExceptionNotHandled

이 이벤트는 서비스 소유 스레드가 예외를 생성하는 경우에 발생합니다. WorkflowRuntimeService 클래스에서 파생된 서비스는 RaiseServicesExceptionNotHandledEvent() 메서드를 호출하여 구독자에게 ServicesExceptionNotHandled 이벤트에 대해 알려 줍니다. 이 이벤트는 실행 중에 예외를 발생시키는데, 이 예외는 처리할 수 없습니다. 기본 서비스는 이러한 조건에서 이 이벤트를 발생시킵니다. 호스트 응용 프로그램은 이 이벤트를 구독하여 복구 메커니즘을 구현할 수 있습니다. 이 이벤트와 관련된 이벤트 인수는 ServicesExceptionNotHandledEventArgs입니다.

WorkflowRuntime.Started

이 이벤트는 WorkflowRuntime의 지정된 인스턴스가 시작되는 경우에 발생합니다. 이 이벤트와 관련된 이벤트 인수는 WorkflowRuntimeEventArgs입니다.

WorkflowRuntime.Stopped

이 이벤트는 WorkflowRuntime의 지정된 인스턴스가 중지되는 경우에 발생합니다. 이 이벤트와 관련된 이벤트 인수는 WorkflowRuntimeEventArgs입니다.

표 1. WorkflowInstanceEvents
이벤트 설명 이벤트 인수
WorkflowAborted 워크플로 인스턴스가 중단되면 발생합니다. WorkflowEventArgs
WorkflowCompleted 워크플로 인스턴스가 완료되면 발생합니다. WorkflowCompletedEventArgs
WorkflowCreated 워크플로 인스턴스가 생성된 후 작업이 처리되기 전(즉, 워크플로가 실행되기 전)에 발생합니다. WorkflowEventArgs
WorkflowIdled 워크플로 인스턴스가 유휴 상태로 들어설 때 다시 말해 외부 이벤트(예: 타이머, 메시지 등)가 실행되는 동안 기다릴 때 발생합니다. WorkflowEventArgs
WorkflowLoaded 워크플로 인스턴스가 일반적으로 보존 저장소에서 메모리로 로드될 때 발생합니다. WorkflowEventArgs
WorkflowPersisted 워크플로 인스턴스가 보존되면 발생합니다. WorkflowEventArgs
WorkflowResumed 워크플로 인스턴스가 일시 중단 상태나 중단 상태에서 다시 시작되는 경우 발생합니다. WorkflowEventArgs
WorkflowStarted 워크플로 인스턴스가 실행되면 발생합니다. WorkflowEventArgs
WorkflowSuspended 워크플로 인스턴스가 일시 중단되면 발생합니다. WorkflowSuspendedEventArgs
WorkflowTerminated 워크플로 인스턴스가 종료되면 발생합니다. WorkflowTerminatedEventArgs
WorkflowUnloaded 워크플로 인스턴스가 메모리에서 보존 저장소로 언로드될 때 발생합니다. WorkflowEventArgs

다양한 이벤트 및 워크플로의 상태 전환 방법에 대한 자세한 내용은 이 기사의 앞부분에 있는 "워크플로 인스턴스 수명 주기 관리" 섹션을 참조하십시오.

다양한 워크플로 런타임 이벤트의 사용 방법에 대한 자세한 내용은 Windows Workflow Foundation SDK Samples를 참조하십시오.

성능 카운터

Windows 성능 도구를 사용하여 워크플로 성능을 모니터링할 수 있습니다. 성능 도구는 시스템 모니터와 성능 로그 및 경고의 두 부분으로 구성되어 있습니다. 성능 로그 및 경고를 통해 성능 카운터를 구성하여 성능 데이터를 기록할 수 있으며, 특정 카운터 값이 정의된 임계값을 넘거나 아래로 내려갈 때 사용자에게 알려 주도록 시스템 경고를 설정할 수 있습니다.

WF에서는 워크플로 성능을 추적하는 데 사용할 수 있는 WF 성능 개체를 성능 카운터 집합에 제공합니다. 성능 카운터의 전체 목록을 보려면 WF SDK의 Workflow Performance Counters 섹션을 참조하십시오.

성능 도구에 성능 카운터를 추가하는 방법에 대한 자세한 내용은 Microsoft TechNet 웹 사이트를 참조하십시오.

언로드 정책

시스템에서는 지정된 시간에 수천 개의 워크플로가 동시에 실행되기도 합니다. 따라서 모든 워크플로를 메모리에 두는 것은 비효율적입니다. 시스템 리소스를 보다 잘 관리하려면 워크플로 상태를 보존한 후 메모리에서 언로드하도록 언로드 정책을 설정하는 것이 좋습니다.

기본 보존 서비스를 사용하는 경우 WF는 유휴 시 언로드 정책을 제공합니다. 이 정책은 SqlWorkflowPersistenceService 클래스에서 UnloadOnIdle 속성을 설정한 경우 활성화되어 유휴 상태일 때 런타임 엔진이 워크플로를 언로드하도록 합니다. 호스트 응용 프로그램이 구성 파일을 통해 SqlWorkflowPersistenceService를 사용할 수 있는 경우 UnloadOnIdle 플래그를 true로 설정하여 이 작업을 수행하면 됩니다. SqlWorkflowPersistenceService가 생성되어 코드를 통해 사용할 수 있는 경우에는 호스트 응용 프로그램이 SqlWorkflowPersistenceService(String, Boolean, TimeSpan, TimeSpan) 생성자를 사용하여 생성하면 됩니다. 호스트 응용 프로그램은 다른 복잡한 언로드 정책도 구현할 수 있습니다.

또한 WorkflowInstance.Unload() 메서드를 호출하여 이러한 특정 워크플로 인스턴스를 메모리에서 언로드한 후 상태를 보존하도록 요청할 수 있습니다. 호스트 응용 프로그램은 나중에 이 인스턴스에 대해 Load() 메서드를 호출하여 마지막 보존 지점부터 인스턴스를 계속 실행할 수 있습니다. 워크플로 인스턴스가 언로드되면 런타임 이벤트인 WorkflowUnloaded 이벤트가 발생합니다.


안정성 및 고가용성

WF에서는 다음 사항을 지원하여 호스트의 안정성 및 고가용성을 지원합니다.

SQL 클러스터링

기본 SQL 기반 서비스는 클러스터링 설치를 지원합니다. WF의 기본 SQL 기반 서비스는 일괄 처리를 SQL Server로 커밋할 때 재시도를 허용합니다. 따라서 장애 조치 시나리오 또는 일시적으로 액세스할 수 없는 SQL 서버를 지원할 수 있습니다. 재시도 논리는 다음 서비스 조합에서 설정할 수 있습니다.

  • DefaultWorkflowCommitWorkBatchService
  • SharedConnectionWorkflowCommitWorkBatchService
  • SqlTrackingService
  • SqlWorkflowPersistenceService

기본적으로 재시도 논리는 OFF로 설정되어 있습니다. 호스트 응용 프로그램이 이 기능을 사용하려면 재시도 논리를 명시적으로 ON으로 설정해야 합니다. 응용 프로그램은 재시도를 서비스 단위로 수행할지 아니면 앞에서 언급된 모든 서비스에 대해 수행할지를 선택할 수 있습니다. 이 작업은 서비스 클래스에서 EnableRetries 속성을 설정하거나 구성 파일을 통해 수행할 수 있습니다. 구성 파일을 사용하는 경우 호스트 응용 프로그램은 공유 플래그인 EnableRetries를 사용하여 영향을 받는 모든 서비스에 대한 재시도 사용 여부를 ON 또는 OFF로 설정할 수 있습니다. 서비스에 EnableRetries 속성을 설정한 경우에는 이 값이 EnableRetries 공유 플래그 값을 덮어쓰게 됩니다. WF의 기본 SQL 기반 서비스는 일정 횟수만큼 재시도를 수행하며, 이 재시도 횟수는 구성할 수 없습니다. 그러나 서비스의 연결 문자열에서 연결 시간 제한을 조정하여 재시도 간격을 부분적으로 조정할 수는 있습니다.

재시도 설정

다음 예제에서는 공용 매개 변수인 EnableRetries를 추가한 후 해당 값을 True로 설정하여 EnableRetries를 모든 기본 서비스에 대해 설정하는 방법을 보여 줍니다. 또한 SqlWorkflowPersistenceService에 대한 EnableRetries 플래그를 추가한 후 이 값을 False로 설정하여 이 서비스에 대해 EnableRetries를 사용하지 않는 방법도 보여 줍니다.

<WorkflowRuntime Name="SampleApplication" UnloadOnIdle="false">
    <CommonParameters>
        <add name="ConnectionString" value="Initial Catalog=WorkflowStore;Data Source=localhost;Integrated Security=SSPI;" />
        <add name="EnableRetries" value="True" />
    </CommonParameters>
    <Services>
        <add type="System.Workflow.Runtime.Hosting.SqlWorkflowPersistenceService,
System.Workflow.Runtime, Version=3.0.00000.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" EnableRetries="False"  />
    </Services>
</WorkflowRuntime>

일반적으로 모든 서비스에 대해 재시도를 ON 또는 OFF로 설정하는 것이 좋습니다.

WorkflowCommitWorkBatchService 클래스는 TransactionScopeActivity가 아닌 다른 모든 작업 관련 일괄 처리 커밋(보존 지점)을 모두 재시도해야 합니다. WorkflowCommitBatchService 클래스는 TransactionScopeActivity 작업에 대한 작업 일괄 처리 커밋을 재시도할 수 없습니다. 이는 트랜잭션를 시작하지 못하여 소유하지 못했기 때문으로, 이런 경우에는 TransactionScopeActivity 작업에 대한 작업 일괄 처리 커밋 재시도를 워크플로로 모델링해야 합니다. 이 작업은 일반적으로 TransactionScopeActivity 외부의 예외 처리기 및 while 루프 형식으로 이루어집니다.

기본 SqlTrackingService 재시도(비트랜잭션 모드에서 실행되는 경우) 및 기본 SqlWorkflowPersistenceService는 작업 일괄 처리 커밋과 관련 없는 SQL 관련 작업을 제어합니다. 여기에는 만료된 타이머에 대한 확인 작업 및 워크플로 인스턴스 로드 작업 등이 포함됩니다.

부하 분산 및 프런트 엔드 크기 조정

WF를 호스팅하는 응용 프로그램은 부하 분산 시나리오 및 프런트 엔드 크기 조정 시나리오를 관리해야 합니다. WF에서는 서로 다른 호스트 응용 프로그램 인스턴스가 동일한 보존 또는 추적 SQL 데이터베이스를 가리킬 수 있도록 돕는 기본 SQL 기반 서비스 및 엔진을 지원합니다.

여러 개의 호스트 응용 프로그램이 동일한 보존 저장소에 연결되어 있는 경우 이 중 어느 응용 프로그램이든지 데이터베이스로부터 모든 형식의 워크플로 인스턴스를 로드할 수 있습니다. WF의 기본 SqlWorkflowPersistenceService에서는 호스트가 동일한 보존 저장소를 공유하더라도 특정 호스트에 로드될 워크플로 형식이나 인스턴스를 할당할 수 없습니다. 이 동작이 사용자의 호스트 응용 프로그램 요구에 맞지 않는 경우에는 사용자 지정 보존 서비스를 구현해야 합니다.

여러 개의 호스트 응용 프로그램이 동일한 보존 저장소를 사용하는 경우 WF 런타임 엔진이 잠금 구문을 제공하여 프런트 엔드 크기 조정 시나리오를 지원합니다. 잠금 구문을 사용하면 한 응용 프로그램에서 이미 로드한 워크플로 인스턴스를 다른 응용 프로그램이 로드할 수 없습니다. WorkflowPersistenceService 클래스를 사용하면 SaveWorkflowInstanceState() 메서드에 매개 변수를 제공하여 데이터 저장소에 있는 워크플로 인스턴스의 상태 정보 잠금 해제 여부를 지정하고, UnlockWorkflowInstanceState() 메서드를 통해 이전에 잠겨 있던 워크플로 상태 정보의 잠금을 해제하여 워크플로 런타임 엔진 기능을 지원할 수 있습니다. 잠금을 구현하는 보존 서비스에서 LoadWorkflowInstanceState() 메서드를 호출하면 워크플로 인스턴스의 상태 정보가 잠깁니다.

워크플로 인스턴스 잠금 구문에 대한 자세한 내용은 WF Programming Guide의 Windows Workflow Persistence Services 및 Creating Custom Persistence Services 섹션을 참조하십시오.


기본 런타임 서비스

WF 런타임 엔진은 런타임 서비스를 사용하여 워크플로를 실행합니다. 런타임 서비스 모델을 통해 호스트 응용 프로그램은 융통성 있게 WF 런타임 엔진에 다양한 서비스를 제공할 수 있습니다. 이 섹션에서는 WF가 제공하는 런타임 서비스 및 이러한 서비스의 기본 구현 방법에 대해 설명합니다.

런타임 서비스 구현에 대한 자세한 내용은 WF Programming Guide의 Windows Workflow Foundation Services 및 Developing Windows Workflow Foundation Services 섹션을 참조하십시오.

WF 런타임은 4개의 서비스를 제공하며, 이러한 서비스는 기본 형태로 구현할 수도 있고 호스트 응용 프로그램이 자체 서비스를 구현하여 워크플로 런타임에 제공할 수도 있습니다.

워크플로 트랜잭션 서비스

Windows 워크플로 트랜잭션 서비스(WorkflowCommitWorkBatchService)는 '보존 지점'이라고 하는 작업 일괄 처리 커밋에 관한 사용자 지정 논리를 사용하기 위한 것입니다. 작업 일괄 처리가 커밋되면 런타임이 현재 트랜잭션 서비스를 호출하고 실제 작업 일괄 처리 커밋을 담당할 대리자를 호출에 전달합니다. 커밋 수행은 여전히 런타임에서 담당하지만 서비스를 프로세스에 삽입하여 커밋 프로세스를 사용자 지정할 수 있습니다.

WF 프레임워크에서는 사용자 소유의 트랜잭션을 외부에서 워크플로 인스턴스로 가져오는 기능을 지원하지 않습니다. WorkflowCommitWorkBatchService가 지원하는 앰비언트 트랜잭션 형식은 워크플로 인스턴스가 생성한 트랜잭션뿐입니다. 워크플로 런타임을 실행하는 호스트 응용 프로그램이 생성한 앰비언트 트랜잭션은 현재 스레드에서 일시적으로 제거되므로 부작용이 줄어듭니다. 워크플로가 유휴 상태를 벗어나면 원본 앰비언트 트랜잭션을 포함하는 호스트 응용 프로그램이 다시 스레드로 돌아옵니다.

WF에서는 트랜잭션 서비스에 대한 두 가지 기본 구현 방법(DefaultWorkflowCommitWorkBatchServiceSharedConnectionWorkflowCommitWorkBatchService)을 제공합니다.

WF 런타임 엔진에는 워크플로 트랜잭션 서비스가 필요합니다. 기본적으로 DefaultWorkflowCommitWorkBatchService가 사용됩니다. 호스트 응용 프로그램은 DefaultWorkflowSchedulerServiceSharedConnectionDefaultWorkflowCommitWorkBatchService 또는 사용자 지정 서비스로 바꿀 수 있습니다.

DefaultWorkflowCommitWorkBatchService

워크플로 런타임 엔진이 시작되면 DefaultWorkflowCommitWorkBatchService 인스턴스가 생성되어 WorkflowRuntime에 추가됩니다(다른 트랜잭션 서비스가 추가되지 않은 경우). 이 서비스는 각 데이터베이스 연결에 대해 .NET Framework 트랜잭션을 생성합니다. 예를 들어 SQL 추적 서비스와 SQL 보존 서비스 간의 연결은 공유되지 않습니다. 사용자의 워크플로에서 이 서비스를 사용하면 데이터 무결성에 필요한 트랜잭션을 지원할 수 있습니다.

SharedConnectionWorkflowCommitWorkBatchService

이 서비스는 여러 개체 간에 공유되는 연결을 사용하는 데이터베이스 트랜잭션에 사용됩니다. 호스트 응용 프로그램이 이 서비스를 사용하려면 AddService 메서드를 사용하거나 구성 파일을 통해 WorkflowRuntime에 서비스를 추가해야 합니다.

워크플로 스케줄러 서비스

워크플로 인스턴스가 비동기 모드에서 처리되는지 아니면 수동 동기 모드에서 처리되는지에 관계 없이 워크플로 스케줄러 서비스는 워크플로 런타임 엔진에서 워크플로 인스턴스를 예약하는 방법을 관리합니다. WF에서는 WorkflowSchedulerService에 대해 두 가지 기본 구현 방법(DefaultWorkflowSchedulerServiceManualWorkflowSchedulerService)을 제공합니다.

워크플로를 실행하기 위해 WF 런타임 엔진에는 워크플로 스케줄러 서비스가 필요합니다. 기본적으로 DefaultWorkflowSchedulerService가 사용됩니다. 호스트 응용 프로그램은 DefaultWorkflowSchedulerServiceManualWorkflowSchedulerService 또는 사용자 지정 서비스로 바꿀 수 있습니다.

DefaultWorkflowSchedulerService

DefaultWorkflowSchedulerService는 워크플로 런타임 엔진에서 워크플로 인스턴스를 비동기 방식으로 실행하는 스레드를 생성 및 관리하며 기본적으로 런타임 스레드 풀에 여러 개의 워크플로 인스턴스가 대기할 수 있도록 지원합니다. WorkflowRuntime에 다른 워크플로 스케줄러 서비스 인스턴스가 추가되지 않은 경우 기본적으로 DefaultWorkflowSchedulerService가 사용됩니다.

ManualWorkflowSchedulerService

ManualWorkflowSchedulerService는 워크플로 인스턴스의 동기식 실행에 사용됩니다. 이 서비스를 사용하는 경우 워크플로 인스턴스는 호스트 응용 프로그램의 호출 스레드에서 실행되므로 워크플로 인스턴스가 유휴 상태로 될 때까지 호스트 응용 프로그램의 실행이 차단됩니다.

워크플로 보존 서비스

보존 서비스는 워크플로 인스턴스 상태의 저장 및 검색(로드 및 언로드)을 담당합니다. WF에서는 보존 서비스에 대한 기본 SQL 기반 구현 방법(SqlWorkflowPersistenceService)을 제공합니다.

SqlWorkflowPersistenceService

이러한 기본 구현은 상태 및 타이머 정보를 SQL Server/MSDE에 저장합니다. SqlWorkflowPersistenceService는 워크플로 트랜잭션에 참여하여 액세스 잠금을 구현합니다. 또한 SqlWorkflowPersistenceService는 SQL 서버를 사용할 수 없는 경우 재시도할 수 있는 기능을 제공합니다. 이 기능은 서비스에서 EnableRetries 속성을 설정하여 제어할 수 있습니다. SqlWorkflowPersistenceService에 대한 자세한 내용은 WF Programming Guide를 참조하십시오.

워크플로 추적 서비스

추적 서비스는 추적 프로필과 추적 정보 저장소를 관리합니다. WF에서는 SqlTrackingService 클래스에서 구현되는 추적 서비스에 대한 기본 SQL 기반 구현 방법을 제공합니다.

SqlTrackingService

이 구현에서는 추적 프로필 및 데이터를 SQL Server/MSDE에 저장합니다. 이 서비스는 다음을 지원합니다.

  • 기본적으로 워크플로 트랜잭션에 참여합니다. 이 동작은 SqlTrackingService.IsTransactional 속성이 제어합니다.
  • 모든 형식에 기본 추적 프로필을 사용하거나 워크플로 형식 또는 워크플로 인스턴스에 따라 추적 프로필을 다르게 연결하는 메커니즘을 제공합니다.
  • 라이브 및 주문형 분할 기능을 제공하여 데이터 유지 관리를 지원합니다.

    데이터 유지 관리에 대한 자세한 내용은 WF Programming Guide의 Data Maintenance with SqlTrackingService 섹션을 참조하십시오.

또한 WF에서는 SqlTrackingService에 저장된 추적 데이터를 쿼리하는 데 사용할 수 있는 SqlTrackingQuery API를 제공합니다. SqlTrackingService에 대한 자세한 내용은 WF Programming Guide를 참조하십시오.


결론

WF에서는 워크플로 실행 및 워크플로 상태 관리를 위한 런타임 엔진과 서비스를 제공합니다. 호스트 응용 프로그램 또는 프로세스는 WF 워크플로를 호스팅할 수 있도록 작성되어야 하며, 이 호스트 응용 프로그램은 워크플로 런타임 엔진에 다양한 런타임 서비스를 제공해야 합니다. WF의 기본 런타임 서비스는 일반적인 시나리오를 따르도록 되어 있지만, 기본 서비스가 호스트 응용 프로그램의 요구에 맞지 않는 경우 호스트 응용 프로그램은 사용자 지정 서비스를 구현하여 워크플로 런타임에 제공해야 합니다.

또한 WF에서는 실행 중인 워크플로 인스턴스를 관리 및 모니터링하고 호스트 응용 프로그램의 안정성 및 고가용성을 지원하기 위한 인프라를 제공합니다. 호스트 응용 프로그램은 호스트 관련 시나리오를 기반으로 하는 다양한 옵션의 사용 방법을 지정해야 합니다.


추가 정보

워크플로 기술을 처음 접하는 개발자들의 경우 다음 리소스와 함께 이 기사를 참조하면 이 기술을 배운 후 활용하여 생산성을 빠르게 향상시킬 수 있을 것입니다.

출처 : 한국 마이크로소프트 MSDN (2006년 8월)