수안이의 컴퓨터 연구실

  • Mainpage
  • About Me
  • Tags
  • Metapage
  • Notice
  • Location
  • Keywords
  • Guestbook
  • Admin
  • Write an Article
  • Total | 1621037
  • Today | 417
  • Yesterday | 482

2 Articles, Search for 'WF'

  1. 2007/07/23 Windows Workflow Foundation 호스팅에 대한 소개
  2. 2007/07/23 Windows Workflow Foundation 규칙 엔진 소개
Programming/.NET2007/07/23 09:41

Windows Workflow Foundation 호스팅에 대한 소개

Moustafa Khalil Ahmed
프로그램 관리자
Microsoft Corporation

2006년 8월

적용 대상:
Windows Workflow Foundation
Microsoft .NET Framework 2.0
Microsoft .NET Framework 3.0

요약: 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는 워크플로 인스턴스 상태에 영향을 줄 수 있는 기본 작업을 제공합니다. 예를 들어 SuspendActivity 및 TerminateActivity 작업을 사용하여 워크플로 인스턴스를 각각 일시 중단하거나 종료할 수 있습니다. 다음 섹션에서는 워크플로 인스턴스의 상태 전환 및 워크플로 인스턴스 이벤트와 통신하기 위해 워크플로 런타임이 발생시키는 다양한 워크플로 인스턴스 관련 이벤트에 대해 설명합니다.

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, WorkflowUnloaded 및 WorkflowLoaded 이벤트를 사용할 수 있는 경우 호스트 응용 프로그램이 이러한 이벤트를 확인할 수 있어야 합니다. 워크플로 인스턴스가 메모리에 없을 때 보존 서비스를 사용하면 워크플로 인스턴스가 먼저 로드된 후 인스턴스에서 유효한 작업(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에서는 트랜잭션 서비스에 대한 두 가지 기본 구현 방법(DefaultWorkflowCommitWorkBatchService와 SharedConnectionWorkflowCommitWorkBatchService)을 제공합니다.

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

DefaultWorkflowCommitWorkBatchService

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

SharedConnectionWorkflowCommitWorkBatchService

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

워크플로 스케줄러 서비스

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

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

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 워크플로 개발자 센터(영문)
    • 웹 캐스트 및 실습에 대한 문서와 링크가 수록되어 있습니다.
  • 커뮤니티 사이트 샘플(영문)
  • Windows SDK 문서(영문)
    • Windows Foundation SDK가 없으면 Windows SDK 사이트 (영문)에서 다운로드하십시오. Windows Workflow SDK (영문)는 Windows SDK의 일부입니다. 여기에는 WF Programming Guide 참조, API 참조 및 다양한 기술 및 응용 프로그램 샘플 (영문)이 수록되어 있습니다.
  • MSDN 워크플로 포럼(영문)
    • WF 런타임 호스팅이나 WF에 대한 일반적인 질문이 있는 경우 이 토론 포럼을 방문하십시오.


저자 소개

Moustafa Khalil Ahmed는 Microsoft Corp.(WA, Redmond)의 WF 팀 프로그램 관리자입니다. 2000년 Microsoft에 입사한 이후 다양한 서버 구성 요소 개발을 담당하고 있으며 Microsoft BizTalk Server를 포함한 4개의 서버 제품 출시에 참여하였습니다. Microsoft에 입사하기 전 Moustafa는 ITWorx(Egypt, Cairo)에서 소프트웨어 엔지니어, 비즈니스 분석가 및 고객 관리자로 일했습니다.

".NET" 카테고리의 다른 글
  • Windows Workflow Foundation 호스팅에 대한 소개 (0)2007/07/23
  • Windows Workflow Foundation 규칙 엔진 소개 (0)2007/07/23
  • Introduction to Windows Communication Foundation (0)2007/06/15
  • High-Performance .NET Application Development &... (0)2007/04/29
  • 데이터 바인딩 어플리케이션 만들기 기초 (0)2007/01/11
2007/07/23 09:41 2007/07/23 09:41
Posted by webdizen
Tags WF, Windows Workflow Foundation
No Trackback No Comment

Trackback URL : http://www.webdizen.net/blog/trackback/3087

Leave your greetings.

[로그인][오픈아이디란?]

Programming/.NET2007/07/23 09:37

Windows Workflow Foundation 규칙 엔진 소개

Jurgen Willis
Microsoft Corporation

업데이트한 날짜: 2006년 2월

적용 대상:
Windows WF(Workflow Foundation) 베타 2
Visual Studio 2005

요약: 이 기사에서는 Windows WF(Workflow Foundation)의 규칙 엔진 기능에 대한 개요를 제공합니다. WF에서 조건과 규칙 집합이 어떻게 사용되는지와 전달 체인, 추적 및 트레이싱을 비롯한 규칙 모음의 동작에 대해서 설명합니다(18페이지/인쇄 페이지 기준).

참고 이 기사는 베타 2를 기준으로 작성되었으므로 여기 설명된 작업을 다음 버전의 Windows Workflow Foundation에서 수행하려면 변경이 필요할 수 있습니다.

목차

소개
Windows Workflow Foundation의 규칙 개요
규칙 평가
전달 체인
전달 체인 제어
추가 모델링 설명
추적 및 트레이싱
결론
추가 정보

소개

Microsoft는 Windows WF(Workflow Foundation)의 출시에 맞춰 WinFX 개발자 플랫폼에 새로운 규칙 기능을 도입했습니다. 새로 도입된 이 기능은 작업 실행 동작을 제어하는 간단한 조건에서부터 모든 기능을 갖춘 전달 체인 규칙 엔진에 의해 실행되는 복잡한 규칙 집합에 이르기까지 다양합니다.

규칙 기능을 사용하면 전체 비즈니스 프로세스 범위 내에서 응용 프로그램 논리 단위의 선언적 모델링이 가능합니다. 규칙 엔진 기술에 대한 샘플 시나리오로 순서 검증, 가격 계산, 홍보 강화, 예외 프로세스 관리, 클래임 판결 및 관리를 들 수 있습니다.

이 기술을 개발한 주요 목적은 워크플로와 규칙이 완전하게 통합된 환경을 제공하기 위해서입니다. 일반적으로 업계 전체에서 규칙과 워크플로는 전혀 다른 기술로 취급되고 있으며 대개 서로 다른 공급업체에 의해 제공됩니다. 타사 규칙 엔진이 워크플로 및 BPM(비즈니스 프로세스 관리) 공급자로부터 기본 제공되거나 통합되는 경우도 종종 있지만 개발자나 관리자 환경이 복잡하고 어려운 것은 확실합니다.

Microsoft는 개발자가 워크플로의 모든 지점에서 규칙을 쉽게 통합할 수 있도록 WF에서 워크플로와 규칙 모델링 간 원활한 연계가 가능한 개발자 환경을 제공하는 데 주력했습니다. 이제 개발자들은 자신의 결정이 통합에 미칠 영향을 걱정하지 않고 워크플로 모델, 규칙, 코드 등 논리를 모델링할 대상을 결정할 수 있습니다. 그러면서도 워크플로 범위 밖에서 규칙을 실행할 수 있는 기능은 그대로 유지됩니다.

두 번째 주요 목적은 개발자들이 규칙 정의에 사용할 수 있는 손쉬운 모델을 제공하기 위한 것입니다. 지금까지 규칙 기술은 뛰어난 전문성을 갖춘 규칙 전문가 그룹에서만 사용하는 틈새 기술이었습니다. 도구의 개선을 통해 규칙 사용자의 범위가 넓어지긴 했지만 모델에 따라 기반 엔진의 구현 기술에 대한 전문가급 지식이 필요한 경우도 종종 있습니다. Microsoft는 플랫폼에서 규칙 기능을 제공함으로써 대다수 .NET 개발자 커뮤니티는 물론 궁극적으로 비개발자들까지도 사용할 수 있는 모델을 채택했습니다. 어떤 기술이든 해당 분야에 대한 일정 수준의 전문 지식이 필요하겠지만 Microsoft의 목표는 모든 .NET 개발자들이 규칙 모델을 빠르게 습득하여 이를 자신의 응용 프로그램에 쉽게 통합할 수 있도록 하는 것입니다.

WF는 사용이 편리한 모델을 제공할 뿐 아니라 전달 체인 평가와 정확한 평가 제어가 필요한 복잡한 규칙 시나리오를 지원하는 강력한 평가 엔진도 제공합니다. 이러한 기능은 다양하게 확장이 가능한 형태로 제공되기 때문에 개발자들은 Microsoft 플랫폼을 기반으로 다양한 시나리오를 지원할 수 있는 규칙 기능을 제공할 수 있습니다.

이 문서에서는 WF에서 제공하는 규칙 기능의 기술적 측면을 소개하고 사용 가능한 기능 및 이러한 기능의 사용법에 대해서 설명합니다. 이 문서의 마지막에는 WF의 규칙 기능을 알아보는 데 참조할 수 있는 추가적인 자료 목록이 나와 있습니다.

Windows Workflow Foundation의 규칙 개요

규칙 기술은 WF에서 작업에 대한 조건과 정책 작업의 전달 체인 규칙 집합이라는 두 가지 주요 방식으로 사용됩니다. 전달 체인에 대해서는 이 문서의 뒷부분에서 설명하겠지만 간단히 말하자면 전달 체인이란 한 규칙의 작업이 다른 종속 규칙을 다시 평가하도록 만드는 기능입니다.

작업 조건

조건은 WF에 제공하는 다음과 같은 네 가지 작업에서 사용됩니다.

  • IfElseBranch
  • While
  • 복제기
  • CAG(ConditionedActivityGroup)

조건은 작업의 실행 동작을 제어하는 데 사용됩니다. 예를 들어 지정된 IfElseBranch의 실행 여부를 결정하는 데 사용될 수 있습니다. 조건은 코드 내에 구성된 처리기가 있는 CodeConditions나 RuleConditionReference의 형태로 지정할 수 있습니다. RuleConditionReference는 워크플로 프로젝트의 워크플로와 연결된 .rules 파일의 RuleCondition 정의를 가리킵니다. 그림 1에서는 Visual Studio에서의 사용 예를 보여 줍니다.

그림 1. WF 규칙 조건 작성

규칙 조건 추가

IfElse 작업 내부의 IfElseBranch 작업에 규칙 조건을 추가하는 단계는 다음과 같습니다.

  1. IfElseBranch와 같이 조건이 있는 작업을 선택하면 Properties 표에 Condition 속성이 표시됩니다.
  2. Condition 속성에 대한 드롭다운에서 CodeCondition 또는 RuleConditionReference를 선택할 수 있습니다.
  3. RuleConditionReference를 선택할 경우 ConditionName 및 Expression 속성이 표시되도록 Condition 속성을 확장할 수 있습니다.
  4. 조건 이름을 입력한 후 Expression 속성의 줄임표를 클릭하여 Rule Condition Editor를 시작합니다. 이 편집기에서는 개발자가 Intellisense와 같은 지원을 통해 텍스트 형태로 조건을 입력할 수 있습니다. 입력한 텍스트는 RuleCondition의 연결된 개체 모델 표현으로 구문 분석됩니다.
  5. OK를 선택하면 RuleCondition 정의가 프로젝트에 추가되는 <WorkflowName>.rules 파일로 serialize됩니다.

편집기에 this.를 입력하면 워크플로의 필드 또는 속성을 참조할 수 있습니다. 점을 입력하면 워크플로의 멤버를 선택할 수 있는 Intellisense와 비슷한 메뉴가 나타납니다. 멤버를 직접 입력할 수도 있습니다. this.order.Total과 같은 중첩 호출도 가능합니다. 코드에서처럼 클래스 이름 다음에 메서드 이름을 입력하여 참조된 형식에 대해 static 메서드를 호출할 수 있습니다.

식에 사용할 수 있는 관계 연산자는 다음과 같습니다.

  • 같음("==" 또는 "=")
  • 보다 큼(">")
  • 크거나 같음(">=")
  • 보다 작음("<")
  • 작거나 같음("<=")

또한 다음과 같은 산술 연산자를 사용할 수 있습니다.

  • 더하기("+")
  • 빼기("-")
  • 곱하기("*")
  • 나누기("/")
  • 나머지("MOD")

다음과 같은 연산자를 사용하여 식을 결합하거나 부정할 수 있습니다.

  • AND("AND", "&&")
  • OR("OR", "||")
  • NOT("NOT", "!")
  • 비트 AND("&")
  • 비트 OR("|")

개발자가 코드 조건 대신 규칙 조건을 사용하는 가장 큰 이유는 규칙 조건은 모델의 일부가 되고 워크플로 인스턴스 실행 시 런타임에 동적으로 업데이트할 수 있기 때문입니다. 규칙 조건의 두 번째 이점은 모델의 일부이기 때문에 모델을 기반으로 정교한 도구를 구축할 수 있어 추가적인 작성 환경을 제공하고 종속성 관리, 조건 간 분석 등의 작업을 지원할 수 있다는 것입니다.

정책 작업

정책 작업은 규칙 집합의 정의와 실행을 캡슐화합니다. 규칙 집합이란 실행 가능한 기능 집합을 갖춘 규칙의 모음이며 규칙은 워크플로 멤버에서 작동하는 If-Then-Else 식입니다. 이에 대한 설명은 그림 2에 나와 있으며 규칙 조건에서 설명한 내용과 유사합니다.

그림 2. WF 규칙 집합 작성

정책 작업 추가

정책 작업에 대한 규칙 집합을 구성하기 위한 단계는 다음과 같습니다.

  1. 도구 상자에서 워크플로 디자이너로 정책 작업을 끕니다.
  2. RuleSetReference에서 규칙 집합의 이름을 입력합니다.
  3. RuleSet Definition 필드에서 줄임표를 선택하여 Rule Set Editor를 시작합니다.
  4. 편집기의 목록 상자에 규칙 모음이 나타납니다.
  5. 규칙을 선택하면 조건, Then 작업, Else 작업 및 추가 속성 집합이 표시됩니다.
  6. Rule Condition Editor에서처럼 텍스트로 조건, Then 작업 및 Else 작업을 입력하여 관련 개체 모델 표현으로 구문 분석합니다. 규칙은 워크플로의 멤버에 대해 작성됩니다.
  7. OK를 선택하면 워크플로와 연결된 .rules 파일로 규칙 집합이 serialize됩니다.

RuleSetReference 속성에서 줄임표를 선택하면 그림 3과 같이 기존 규칙 집합을 선택하거나 규칙 집합을 추가 또는 제거하거나 이름을 바꿀 수 있는 편집기가 시작됩니다.

그림 3. WF 규칙 집합 브라우저

규칙 평가

규칙 집합의 각 규칙에는 기본값이 0인 우선 순위 값이 있습니다. 규칙 집합의 규칙은 우선 순위 값에 따라 정렬된 컬렉션으로 간주할 수 있습니다. WF 규칙 평가기는 규칙을 개별적으로 평가하고 규칙의 조건 평가 결과에 따라 규칙의 작업을 실행합니다.

평가 방식은 다음과 같은 절차를 통해 개념적으로 설명할 수 있습니다.

  1. 활성 규칙의 목록을 대상으로 평가가 시작됩니다.
  2. 가장 높은 우선 순위를 가진 규칙을 찾습니다.
  3. 규칙을 평가하고 Then/Else 작업을 적절히 실행합니다.
  4. 규칙의 작업이 목록에 있는 우선 순위가 높은 이전 규칙에서 사용한 필드/속성을 업데이트할 경우 이전 규칙을 다시 평가하고 Then/Else 작업을 적절히 실행합니다. 이때 현재 규칙과 종속성이 있는 규칙만 다시 평가됩니다.
  5. 규칙 집합의 모든 규칙을 평가할 때까지 프로세스를 계속합니다.

간단한 예제를 살펴보도록 합시다. 다음과 같은 규칙 집합이 있다고 가정하는데 여기서 A와 B 등의 알파벳은 워크플로의 데이터를 나타냅니다.

규칙4(우선 순위=4)

IF A = 15
THEN B = 5

규칙3(우선 순위=3)

IF C = 5
THEN B = 10

규칙2(우선 순위=2)

IF D = 2
THEN A = 15

규칙1(우선 순위=1)

IF B = 5
THEN E = 7

다음과 같은 입력 데이터가 있다고 가정해 봅시다.

  • A = 0
  • B = 0
  • C = 5
  • D = 2
  • E = 0

평가는 다음과 같이 진행됩니다.

  • 규칙4를 평가합니다. 결과는 false이며 Else 작업이 없기 때문에 더 이상 작업이 실행되지 않습니다.
  • 규칙3은 true로 평가되므로 B = 10으로 설정하는 작업이 실행됩니다. 규칙4는 B의 값에 종속적이지 않으므로 규칙2 평가로 넘어갑니다.
  • 규칙2가 true로 평가되어 A = 15로 설정하는 작업이 실행됩니다.
  • 규칙4는 조건에 A의 값을 사용하므로 A의 값이 다시 평가됩니다. 결과는 true이며 B = 5로 설정하는 작업이 실행됩니다. 규칙3과 규칙2는 조건이 A의 값에 종속적이지 않으므로 다시 평가되지 않습니다. 앞의 어떤 규칙도 B의 값에 종속적이지 않으므로 규칙1 평가로 넘어갑니다.
  • 규칙1이 true로 평가되고 E = 7로 설정하는 작업이 실행됩니다.

결과 데이터 집합은 다음과 같습니다.

  • A = 15
  • B = 5
  • C = 5
  • D = 2
  • E = 7
전달 체인

앞서 살펴보았듯이 체인은 규칙 간 식별된 종속성을 기준으로 합니다. 보다 구체적으로 말하자면 한 규칙의 작업과 다른 규칙의 조건 간의 종속성을 기준으로 한다고 할 수 있습니다. 이러한 종속성은 다음 세 가지 방법 중 하나로 식별하거나 선언할 수 있습니다.

  • 암시적
  • 특성 기반
  • 명시적
암시적

암시적 종속성은 엔진에 의해 자동으로 식별됩니다. 규칙 집합이 처음 실행되면 규칙의 조건에서 읽거나 작업에 쓰는 필드/속성을 평가하여 각 규칙을 분석합니다. 이러한 분석은 조건의 식과 작업의 문을 순서에 따라 평가하는 방식으로 수행됩니다. 예를 들어 다음과 같은 규칙이 있다고 가정해 봅시다.

규칙1

IF this.subtotal > 10000
THEN this.discount = .05

규칙2

IF this.discount > 0
THEN this.total = (1-this.discount) * this.subtotal

엔진은 규칙을 평가하여 규칙1이 subtotal 필드를 읽고 discount 필드를 쓴다는 사실을 확인합니다. 규칙2는 discount 및 subtotal 필드를 읽고 total 필드를 씁니다. 따라서 규칙2는 규칙1에 종속되므로 엔진에서는 규칙1이 Then 작업을 실행할 때마다 규칙2가 평가 또는 다시 평가되도록 합니다.

종속성은 리프 노드 수준에서 식별됩니다. 다음 규칙 집합을 예로 들어 보겠습니다.

규칙1

IF this.order.Subtotal > 10000
THEN this.order.Discount= .05

규칙2

IF this.order.Discount > 0
THEN this.order.Total = (1-this.order.Discount) * this.order.Subtotal

규칙3

IF this.order.CustomerType = "Residential"
THEN ...

여전히 규칙1과 2 사이에는 종속성이 있지만 규칙1 또는 2 중 어느 것도 CustomerType 속성을 업데이트하지 않으므로 규칙3은 이러한 규칙에 종속되지 않습니다. 즉, 종속성은 Order 개체 자체가 아닌 CustomerType 속성 수준에서 식별됩니다.

WF는 암시적 체인을 통해 사용자에게 필요한 체인 작업 중 대부분을 처리하므로 사용자는 명시적으로 모델을 업데이트할 필요가 없고 사실상 대부분의 경우 체인이나 체인의 필요성에 대해 알 필요가 없습니다. 암시적 체인은 복잡한 규칙 집합의 모델링을 보다 용이하게 하며 더욱 강력하면서도 대부분의 작업을 보이지 않게 수행하는 엔진의 기능을 담당하게 됩니다. 그러나 보다 복잡하고 구체적인 시나리오에 사용할 수 있도록 특성 기반 체인과 명시적 체인을 제어하는 두 가지 다른 방법도 제공됩니다.

특성 기반

규칙 내 메서드 호출의 경우 수행되는 읽기 및 쓰기를 명확하게 평가하는 것이 더욱 어렵습니다. 이 문제를 해결하기 위해 WF에서는 메서드에 적용하여 각 작업의 종류를 표시할 수 있는 다음과 같은 세 가지 특성을 제공합니다.

  • RuleRead
  • RuleWrite
  • RuleInvoke

메서드에 RuleRead 특성을 지정하면 메서드가 표시된 속성을 읽음을 나타냅니다. 마찬가지로 RuleWrite 특성은 메서드가 특정 필드 또는 속성을 업데이트함을 표시하는 데 사용할 수 있습니다. 암시적 종속성에서 사용한 첫 번째 두 규칙이 다음과 같이 다시 작성되었다고 가정해 봅시다.

규칙1

IF this.subtotal > 10000
THEN this.SetDiscount(.05)

규칙2

IF this.discount > 0
THEN this.total = (1-this.discount) * this.subtotal

SetDiscount 메서드는 다음과 같이 특성을 지정할 수 있으며, 이렇게 하면 규칙2가 discount 필드를 사용하므로 규칙1에 종속되어 있음을 엔진에서 식별할 수 있게 됩니다.

[RuleWrite("discount")] 
void SetDiscount(double requestedDiscount)
{
...//discount 필드를 업데이트하는 코드
}(참고: 프로그래머 코멘트는 샘플 프로그램 파일에는 영문으로 제공되며 기사에는 설명을 위해 번역문으로 제공됩니다.)

RuleInvoke 특성은 연결된 메서드 호출로 인한 종속성을 나타내는 데 사용할 수 있습니다. 예를 들어 규칙과 메서드를 다음과 같이 수정한다고 가정해 봅시다.

규칙1

IF this.subtotal > 10000
THEN this.SetDiscountWrapper(.05)

규칙2

IF this.discount > 0
THEN this.total = (1-this.discount) * this.subtotal
[RuleInvoke("SetDiscount")]
void SetDiscountWrapper(double requestedDiscount)
{
...
SetDiscount(requestedDiscount);
...
}

[RuleWrite("discount")]
void SetDiscount(double requestedDiscount)
{
}

규칙2의 조건은 SetDiscountWrapper를 호출하고 이 메서드는 discount 필드에 값을 쓰는 SetDiscount를 호출합니다. RuleInvoke 특성을 사용하면 이러한 간접 쓰기를 선언하여 엔진에서 감지하도록 할 수 있습니다.

특성 경로에서 참조되는 필드나 특성은 메서드와 동일한 클래스의 필드나 특성을 참조한다는 점이 중요합니다. 실행을 위해 규칙 집합에 반드시 루트 개체를 전달할 필요는 없기 때문입니다. 예를 들어 Order의 특성을 다음과 같이 지정할 수 있습니다.

public class Order
{
private double discount;

public double Discount
{
get { return discount;}
set { discount = value;}
}

[RuleWrite("Discount")]
void CalculateDiscount(double requestedDiscount, double weighting)
{
...//discount 필드를 업데이트하는 코드
}
}

그런 다음 워크플로에서 이 클래스를 다음과 같이 사용할 수 있습니다.

public class Workflow1 :  SequentialWorkflowActivity
{
private Order discount;

...
}

규칙2를 실행하면 규칙1이 다시 평가됩니다.

규칙1

IF this.order.Discount > 5
THEN ...

규칙2

IF ...
THEN this.order.CalculateDiscount( 5.0, .7)

특성 사용에 관해 알아두어야 할 몇 가지 추가적인 사항은 다음과 같습니다.

  • 특성은 메서드 호출에 대한 매개 변수가 아닌 Owner 클래스의 필드/속성을 가리킵니다.
  • 규칙 특성에 와일드카드도 사용할 수 있습니다. 예를 들어 RuleWrite("order/*")를 사용하여 "order" 필드에서 참조하는 개체의 모든 필드가 이 메서드에 의해 수정됨을 나타낼 수 있습니다. 이 예에서는 메서드가 Order 클래스가 아닌 워크플로 자체에 있습니다. 그러나 와일드카드는 경로의 끝에서만 사용할 수 있습니다. RuleWrite("*/Discount")와 같은 특성은 올바르지 않습니다.
  • RuleWrite("order")와 같은 특성을 참조 형식과 함께 사용하여 참조가 변경되었음을 나타낼 수 있습니다. 예를 들어 변수가 이제부터는 다른 Order 인스턴스를 가리킴을 나타낼 수 있습니다. IF this.order == this.order2와 같이 인스턴스 참조 자체를 테스트하는 모든 규칙뿐 아니라 변수의 필드/속성을 사용하는 모든 규칙은 영향을 받는 것으로 가정합니다.
  • 메서드 특성을 지정하지 않는 경우 기본 동작은 메서드 호출에서 대상 개체, 즉 메서드가 호출된 개체의 모든 필드/속성을 읽기는 하지만 이러한 필드/속성 중 어느 것에도 쓰지는 않는 것으로 가정합니다. 또한 메서드는 전달된 매개 변수를 읽지만 이러한 매개 변수 중 어느 것에도 쓰지는 않는 것으로 가정합니다. Out 및 ref 매개 변수는 규칙 작업에 사용될 경우 데이터가 기록되는 것으로 가정합니다.
명시적

필드/속성 종속성을 나타내는 마지막 방법은 Update 문을 사용하는 것입니다. Update 문은 필드/속성의 경로를 나타내는 문자열이나 필드/속성 액세스를 나타내는 식을 인수로 취합니다. 예를 들어 다음 두 문 중 하나를 규칙 집합 편집기에 입력하면 워크플로의 Customer 인스턴스의 Name 속성에 Update 문을 생성할 수 있습니다.

Update("this/customer/Name") 

또는

Update(this.customer.Name)

Update 문은 규칙이 표시된 필드/속성에 값을 기록함을 나타냅니다. 따라서 Update 문은 규칙의 필드/속성에 직접 값을 설정하거나 필드/속성에 대해 RuleWrite 특성을 사용하는 메서드를 호출하는 것과 결과가 동일합니다.

Update 명령 역시 와일드카드 사용을 지원합니다. 예를 들어 규칙에 다음 Update 명령을 추가할 수 있습니다.

Update("this/customer/*")

그러면 조건에 Customer 인스턴스의 속성을 사용하는 모든 규칙이 다시 평가됩니다. 즉, 다음과 같은 두 개의 규칙은 각각 다시 평가됩니다.

IF this.customer.ZipCode == 98052
THEN ...

IF this.customer.CreditScore < 600
THEN ...

일반적으로 대부분의 상황에서 사용자가 명시적으로 Update 문을 모델링할 필요는 없습니다. 대개 필요한 종속성 분석과 체인 동작은 암시적 체인을 통해 제공되고 암시적 체인에서 종속성을 식별할 수 없는 경우에는 메서드 특성 지정이 주로 사용됩니다. 일반적으로 메서드에서 종속성을 한 번 식별하고 해당 메서드를 사용하는 많은 규칙에서 그 종속성을 활용할 수 있기 때문에 메서드 특성 지정이 Update 문을 사용하는 것보다 종속성을 나타내는 데 선호되는 방법입니다. 또한 규칙 작성자와 메서드를 구현한 사람이 다르거나 다른 시간에 작업한 경우 메서드 특성 지정을 사용하면 코드에 대해 가장 잘 아는 메서드 작성자가 메서드의 종속성을 식별할 수 있습니다.

그러나 다음 코드에서처럼 워크플로 작성자가 제어하지 않기 때문에 특성을 지정할 수 없는 클래스의 메서드로 필드/속성이 전달되는 경우와 같이 Update 문이 더 적합한 경우도 있습니다.

IF ...
THEN this.customer.UpdateCreditScore(this.currentCreditScore)
Update(this.currentCreditScore)
전달 체인 제어

전달 체인은 규칙 간 종속성에 대한 정의 또는 종속성에 대한 지식 없이도 개별 규칙을 규칙 집합으로 그룹화할 수 있는 매우 강력한 개념입니다.

그러나 일부 시나리오에서는 규칙 작성자가 체인 동작을 보다 잘 제어할 수 있는 기능, 특히 체인 연결을 제한하는 기능이 필요할 수 있습니다. 이 기능을 사용하면 규칙을 모델링하는 사람이 다음과 같은 작업을 수행할 수 있습니다.

  • 잘못된 결과를 초래할 수 있는 규칙의 반복 실행 제한
  • 성능 향상
  • 무한 루프 방지

이러한 고급 제어는 WF 규칙에서 다음과 같은 두 가지 속성에 의해 가능합니다.

  • 규칙 집합의 Chaining Behavior 속성
  • 각 규칙의 Reevaluation Behavior 속성

이러한 속성값은 RuleSet Editor에서 설정할 수 있습니다.

Chaining Behavior 속성

규칙 집합의 Chaining Behavior 속성에 사용할 수 있는 값은 다음 세 가지입니다.

  • Full Chaining
  • Explicit Chaining
  • Sequential

Full Chaining 옵션은 기본값이며 지금까지 설명한 방식에 해당합니다. Explicit Chaining 옵션을 선택하면 암시적 체인과 특성 기반 체인이 해제되고 명시적 Update 문에 대해서만 체인이 연결됩니다. 이렇게 하면 규칙 작성자가 어떤 규칙에 의해 다시 평가 과정이 실행될지를 완벽하게 제어할 수 있습니다. 일반적으로 이 옵션은 과도하게 또는 무한적으로 규칙을 다시 평가하게 되는 순환 종속성을 방지하거나 규칙 집합의 기능적 완전성을 제공하는 데 필요하지 않은 규칙 다시 평가 과정을 제거함으로써 성능을 향상시키기 위해 사용합니다.

마지막 옵션은 Sequential입니다. 이 옵션을 선택하면 엔진이 엄격하게 순차적 방식으로 규칙을 다시 평가하게 됩니다. 각 규칙은 우선 순위에 따라 한 번씩만 평가되며 우선 순위가 높은 규칙은 우선 순위가 낮은 규칙에 영향을 미칠 수 있으나 반대 방향으로는 체인이 연결되지 않기 때문에 영향을 미치지 않습니다. 따라서 이 옵션은 규칙 간 종속성이 있는 경우 명시적 우선 순위를 지정하여 사용해야 합니다.

Reevaluation Behavior 속성

규칙의 Reevaluation Behavior 속성에 사용할 수 있는 값은 다음 두 가지입니다.

  • Always
  • Never

Always는 기본값으로 지금까지 설명한 방식에 해당합니다. 즉, 체인 연결에 따라 다른 규칙의 작업으로 인해 규칙이 항상 다시 평가됩니다. Never는 이름에서 알 수 있듯이 이러한 다시 평가 기능을 해제합니다. 규칙은 한 번만 평가되며 앞서 작업을 수행한 경우에도 다시 평가되지 않습니다. 즉, 규칙이 이전에 평가되고 그 결과로 Then 또는 Else 작업이 수행된 경우 이 규칙은 다시 평가되지 않습니다. 그러나 Then 또는 Else 작업에서 아무 것도 실행하지 않은 경우에는 규칙이 실행된 것으로 표시되지 않습니다.

일반적으로 이 속성은 규칙이 자체 작업이나 다른 규칙에 대해 가지는 종속성으로 인해 무한 루프가 발생하는 것을 방지하기 위해 규칙 수준에서 사용됩니다. 예를 들어 다음 규칙은 자체 무한 루프를 생성하며 이 규칙의 기능적 요구 사항을 충족시키기 위해 다시 평가할 필요가 없습니다.

IF this.shippingCharge < 2.5 AND this.orderValue > 100
THEN this.shippingCharge = 0

또한 규칙을 다시 평가하더라도 OrderValue 필드만 변경된 경우 사용자는 명시적 Update 문에 대해서만 체인을 연결하고 이 Update 문을 관련 규칙 작업에 추가하도록 규칙 집합의 체인 동작을 설정할 수 있습니다. 물론 이 규칙에 ShippingCost의 값이 이미 0이 아닌지 확인하는 조건을 추가할 수도 있지만 체인 제어를 사용하면 업무 요구 사항과는 달리 평가 세부 정보를 기준으로 규칙을 정의해야 할 필요성을 없애 줍니다.

Halt 함수

마지막 제어 방법으로 Halt 함수를 규칙 작업으로 추가하는 방법을 들 수 있습니다. 편집기의 Then 또는 Else 작업 부분에 "Halt"만 입력하면 됩니다. 그러면 규칙 집합의 실행이 즉시 중지되고 호출 코드로 제어권이 되돌아갑니다. 물론 이 함수는 체인 제어 이외의 경우에도 사용할 수 있습니다. 한 예로 특정 기능을 위한 규칙 집합에서 Halt 함수를 사용하여 목표가 달성되면 실행 순환 주기를 단축할 수 있습니다.

추가 모델링 설명 우선 순위 기반 실행

앞서 설명했듯이 사용자가 규칙 집합이나 해당 규칙 집합에 있는 규칙의 하위 집합에 특정 실행 순서를 적용하려는 경우 규칙에 우선 순위 필드를 사용하여 이 순서를 정확하게 정의할 수 있습니다. 이렇게 하면 체인을 사용할 필요가 없어지는 경우가 종종 있으므로 체인 기능을 해제할 수도 있습니다. 많은 경우 명시적 실행 순서를 제공하는 것만으로도 규칙 종속성이 충족되는 것으로 나타났습니다.

그러나 중요한 것은 WF의 전달 실행 방식을 통해 사용자가 실행 순서를 정의할 수 있으나 반드시 정의해야 하는 것이 아니라는 점입니다. 대부분의 경우 규칙 종속성이 충족되도록 엔진에 의해 관계가 자동으로 관리되므로 전달 체인 동작이 수행되면 규칙 우선 순위를 지정하지 않아도 정확한 규칙 집합 결과를 얻을 수 있습니다.

다음과 같은 규칙을 예로 들어 봅시다.

규칙1

IF this.Weather.Temperature < 50
THEN this.Drink.Style = "Latte"

규칙2

IF this.Drink.Style == "Latte"
THEN this.Snack.Style = "Scone"
ELSE this.Snack.Style = "Muffin"

WF에서는 규칙1이 먼저 실행되도록 더 높은 우선 순위를 지정할 수 있습니다. 이렇게 함으로써 규칙2가 평가되기 전에 Drink.Style이 설정됩니다.

그러나 원하는 결과를 얻기 위해 반드시 순서를 지정할 필요는 없습니다. 규칙2가 먼저 평가되었다고 가정해 봅시다. 이 경우 Drink.Style은 null이거나 다른 스타일일 수 있습니다. 그러면 Snack.Style이 Muffin으로 설정됩니다. 그러나 규칙1이 실행되고 Drink.Style을 Latte로 설정하면 규칙2가 다시 평가되므로 Snack.Style은 Scone으로 설정됩니다. 즉, 기본적으로 사용자는 순서를 지정할 수 있으나 그럴 필요가 없는 경우가 많습니다.

컬렉션 처리

어떤 경우에는 컬렉션에 있는 모든 항목에 대해 규칙을 평가해야 할 수 있습니다. 컬렉션에 대한 반복은 여러 가지 방법으로 수행될 수 있으나 그 중 한 가지 방법은 다음과 같은 규칙 패턴을 사용하는 것입니다.

규칙1(우선 순위=2)

//항상 이 규칙을 한 번 실행하여 열거자 생성
IF 1==1
THEN this.enumerator = this.myCollection.GetEnumerator()

규칙2(우선 순위=1)

IF this.enumerator.MoveNext()
THEN this.currentInstance = this.enumerator.Current

규칙3-N(우선 순위=0)

.... //this.currentInstance에 대해 작성된 추가적인 규칙

규칙N+1(우선 순위=-1)

// 항상 평가되는 조건
// this.currentInstance는 매번 평가됩니다.
//this.currentInstance는 변경되지만
// "1==1"은 한 번만 평가됩니다
IF this.currentInstance == this.currentInstance

THEN ...
Update("this/enumerator") //이로 인해 규칙2가 다시 평가됩니다
ELSE ...
Update("this/enumerator")
추적 및 트레이싱 추적

호스트에서 추적 프로파일에 UserTrackPoint를 추가하여 추적 이벤트를 등록하면 규칙 집합 실행 시 호스트에 구성된 추적 서비스로 추적 이벤트가 전송됩니다. 전송되는 RuleActionTrackingEvent는 평가되는 규칙 이름뿐 아니라 조건 평가 결과(true/false)를 제공합니다. 이에 대한 예는 SDK의 RuleActionTrackingEvent 샘플을 참조하십시오.

작업에 대한 규칙 조건의 평가 결과는 추적 작업 실행을 통해 간접적으로 추적할 수 있습니다.

트레이싱

응용 프로그램 구성 파일에 다음과 같은 항목을 추가하면 추가적인 규칙 집합 평가 정보를 로그 파일로 전송할 수 있습니다.

<configuration>
<system.diagnostics>
<switches>
<add name="Rules" value="Information"/>
</switches>
</system.diagnostics>
</configuration>

다음과 같은 정보가 로그 파일로 전송됩니다.

  • 조건 종속성 정보:
    • 예: Rule "ReturnNumberOfStops" Condition dependency: "this/currentFlight/OutboundFlight/NumberOfStops/"
  • 파생 작업에 대한 정보:
    • 예: Rule "ReturnNumberOfStops" THEN side-effect: "this/currentFlight/Score/"
  • 체인 관계:
    • 예: Rule "ReturnNumberOfStops" THEN actions trigger rule "ApprovedFlights"
  • 작업 집합 실행:
    • 예: Rules: "Executing RuleSet FlightRuleSet"
  • 조건 평가:
    • 예: Rules: Evaluating condition on rule "SetDefaultScore"
  • 조건 평가 결과:
    • 예: Rules: Condition evaluated to True
  • 작업 실행:
    • 예: Rules: Evaluation THEN actions for rule"SetDefaultScore"

모든 트레이싱 메시지는 현재 "정보" 수준으로 정의되어 있으므로 규칙 트레이싱을 보려면 구성 파일에서 정보의 수준이나 세부 내용 표시 기준을 조정해야 합니다.

결론

WF는 여러 가지 방법으로 활용하여 다양한 시나리오를 지원할 수 있는 유연한 규칙 기능을 제공합니다. 간단한 작업 조건에서 복잡한 전달 체인 규칙 집합에 이르기까지 이 기술을 사용하면 규칙에 대한 지원을 워크플로에 원활히 통합할 수 있습니다. 또한 모든 .NET 응용 프로그램에 규칙 기능을 제공하기 위해 워크플로 외부에서 규칙 엔진을 사용할 수도 있습니다.

이러한 기능을 통해 사용하면 고급 규칙 집합 및 응용 프로그램 시나리오를 지원할 수 있는 다양성과 확장성은 그대로 유지하면서도 신규 개발자들이 워크플로에 간단한 규칙을 쉽게 통합할 수 있습니다. 다음 섹션에서 소개하는 자료와 함께 이 문서를 참조함으로써 WF 규칙을 처음 접하는 개발자들은 이 기술을 배우고 활용하며 빠르게 생산성을 향상시킬 수 있을 것입니다.

추가 정보
  • MSDN 워크플로 사이트(영문)

    웹캐스트 및 실습에 대한 다양한 문서 및 링크 수록

  • 커뮤니티 사이트 샘플(영문)
    • 외부 규칙 집합 툴킷 워크플로 어셈블리의 외부로 규칙을 분리하는 방법에 대한 예제를 제공합니다.
    • 규칙 집합 분석 규칙 집합에서 규칙 간 그리고 규칙과 데이터 간 관계를 분석할 수 있는 도구입니다.
    • Excel의 규칙 워크플로와 상관없이 규칙을 독립적으로 사용하는 방법에 대한 예제를 제공합니다. Excel의 결정 테이블을 통해 작성된 규칙을 프로그래밍 방식으로 만드는 방법도 설명합니다.
  • SDK 샘플
    • IfElseWithRules IfElse 작업에서 RuleCondition을 사용하는 방법을 보여 줍니다(\Technologies\RulesAndConditions).
    • DynamicUpdateChangingRules 동적 업데이트 API를 사용하여 실행 중인 워크플로 인스턴스에서 RuleCondition을 변경하는 방법을 보여 줍니다(\Technologies\RulesAndConditions).
    • SimplePolicy API를 사용하여 간단한 규칙 집합과 정책 작업을 정의하는 방법을 보여 줍니다(\Technologies\Activities\Policy).
    • AdvancedPolicy 보다 복잡한 규칙 집합을 정의합니다(\Technologies\Activities\Policy).
    • RuleActionTrackingEventSample 추적 공급자에서 규칙 평가 결과를 수집하는 방법을 보여 줍니다(\Technologies\Tracking).
  • MSDN 워크플로 포럼(영문)
    • WF 규칙이나 WF의 전반적인 부분에 대한 질문이 있는 경우 이 토론 포럼을 방문하십시오.

저자 소개

Jurgen Willis는 Windows Workflow Foundation 팀의 프로그램 관리자로 규칙 엔진 기술과 규칙 기반 작업을 책임지고 있습니다. Microsoft에 합류하기 전 Jurgen은 Fortune지 선정 500대 기업에 대한 통합 및 프로세스 관리 솔루션을 설계 및 구현했습니다.

".NET" 카테고리의 다른 글
  • Windows Workflow Foundation 호스팅에 대한 소개 (0)2007/07/23
  • Windows Workflow Foundation 규칙 엔진 소개 (0)2007/07/23
  • Introduction to Windows Communication Foundation (0)2007/06/15
  • High-Performance .NET Application Development &... (0)2007/04/29
  • 데이터 바인딩 어플리케이션 만들기 기초 (0)2007/01/11
2007/07/23 09:37 2007/07/23 09:37
Posted by webdizen
Tags WF, Windows Workflow Foundation
No Trackback No Comment

Trackback URL : http://www.webdizen.net/blog/trackback/3085

Leave your greetings.

[로그인][오픈아이디란?]

«Prev  1  Next»

RSS HanRSS
Blog Image
webdizen
이 곳은 컴퓨터에 대해 연구하고, 공유하고, 소통하기 위한 연구실입니다. 개인적으로는 OLAP, Data Mining, Semantic Web, Data Modeling에 대해서 연구하고 있습니다.

Categories

전체 (2998)
Webdizen (134)
Life (6)
Diary (16)
Blog (9)
IDEA (1)
Travel (10)
Book (14)
Photo (7)
Movie (7)
Music (13)
Leisure Sports (10)
Funny (5)
Hardware (119)
Software (120)
Windows (5)
Unix & Linux (119)
Installation (4)
Kernel (10)
System (34)
Develop (22)
X-Window (0)
Applicaton (31)
Security (4)
Framework (2)
Hadoop (2)
Programming (805)
Algorithm & Data Structure (1)
Assembly (38)
UNIX/Linux C (95)
C++ (128)
STL (4)
Java (38)
Win32 API (92)
ATL/COM (44)
MFC (151)
.NET (26)
WCF/WPF (4)
C# (28)
Network Programming (17)
Database Programming (12)
OpenGL / DirectX (13)
Multimedia Programming (0)
Game Programming (21)
Parallel Distributed Progra... (0)
Reverse Engineering (0)
Debugging (9)
Python (1)
Ruby (1)
Ruby on Rails (1)
QT (4)
GTK (0)
JSP (0)
PHP (6)
ASP.NET (6)
ASP (3)
Development (28)
Useful Library (2)
Data Modeling (0)
Database (105)
Oracle (4)
MSSQL (41)
MySQL (2)
Data Warehouse (2)
Data Mining (3)
Network (66)
Web (78)
DHTML (4)
XHTML (1)
Javascript (1)
CSS (1)
AJAX (9)
XML (11)
Flex (1)
Silverlight (3)
Security (91)
DoS (1)
Kernel (10)
Scanning (3)
Sniffing (0)
Spoofing (4)
Overflow (28)
Web (11)
Shell (10)
Format String (14)
Window (2)
Embedded (70)
Multimedia (27)
Mobile (14)
Graphic (24)
Management (633)
Knowledge (581)
Hadoop (0)

Notice

  • 메타 블로그 사이트에 등록
  • 새해 맞이 블로그의 변화
  • 블로그 명칭 변경
  • 도메인(www.webdizen.net) 구...
  • TEXTCUBE 1.6.1로 업그레이드...

Tags

  • Profiling
  • eCommerce
  • 헤네지 XO
  • Ontology
  • 엔터티빈
  • Goowy
  • Data Binding
  • 메모리 오류
  • 서비스팩 3
  • FOR XML
  • Unicode
  • Calendar
  • 병렬화
  • ToolBar
  • DB
  • FlashWindow
  • 사그라다 파밀리아
  • The Secret
  • JSP
  • 중앙교육연구전산원

Recent Articles

  • ASCII Code의 CRLF 제거 방법.
  • Hadoop 에서 c++ API 이용시....
  • Ubuntu Linux에서 Hadoop 구....
  • 내 심장을 한껏 뛰게한 "국가....
  • 스타 스키마 데이터베이스 설....

Recent Comments

  • ■ 온라인카지노 ▶ http://L....
    asdf 11/21
  • 그리고 혹시 해외여행자보험....
    kim 11/05
  • ★★실제 바다게임장과 똑같....
    asdf 11/04
  • sbsyama.co.to← 짱5000만당....
    asdf 11/04
  • ♡KicaZ??o(???) 바카라사....
    fdsf3fass 11/03

Recent Trackbacks

  • 파일 열기/저장하기 CFileDialog.
    은마군의 나태블록 02/11
  • World IT Show 2008.
    상우 :: Oranzie's BLOG 2008
  • cvs서버 설치하기.
    3인3색 2008
  • 속속 공개되는 Google Chart....
    PHP와 Web 2.0 2007
  • 마방진을 구하는 프로그램.
    Oranzie's BLOG 3 2007

Archive

  • 2009/09 (3)
  • 2009/08 (1)
  • 2009/03 (1)
  • 2009/02 (9)
  • 2009/01 (13)

Calendar

«   2009/11   »
일 월 화 수 목 금 토
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30          

Bookmarks

    • Administration
      • IIS.NET
      • NTFAQ
      • OS의 모든 것
      • 리눅스포털
    • Database
      • SQL Server Central
      • SQL Team
    • Development
      • .NET Heaven
      • ASP Alliance
      • ASP.NET 2.0
      • Bullog.net
      • C# Corner
      • C++ (C PlusPlus.com)
      • C++ Reference
      • CodeGuru
      • CodePlex
      • DebugLab
      • Dev Articles
      • Devpia
      • DotNet Junkies
      • DotNet Zone
      • Driver Online
      • GOSU.NET
      • HOONS 닷넷
      • Joinc 팀블로그
      • KOSR
      • MSDN Home Page
      • OSR Online
      • Sky.ph - 개발자 커뮤니...
      • TAEYO.NET
      • The Code Project
      • WindowsClient.net
      • 김상욱의 개발자 Side
      • 조인시 위키
    • Human Networks
      • belief21c's e-space
      • I think I can
      • Invisible Rover's Blog :D
      • Rodman®
      • ■ Feel So Good~! ■
      • 까만 나비
      • 나를 가꾸는 시간.
      • 나만의 즐거움~~!
      • 단녕
      • 상우 :: Oranzie's BLOG
    • Information Technology
      • Microsoft TechNet
      • 지디넷코리아 - 글로벌...
    • Security
      • FoundStone
      • milw0rm
      • NewOrder
      • OpenRCE
      • Phrack.org
      • Reverse Engineering b1...
      • Reverse Engineering Team
      • RootKit
      • SecurityFocus
      • SecurityXploded by Nag...
      • Wow Hacker
      • Zone-H
Textcube
Louice Studio Inc.
Powered by Textcube. Original designed by Tistory.