Share via


カスタム追跡サービスの作成

Windows Workflow Foundation には、ホスティング環境にプラグインしたり、すぐに使用したりできるいくつかのサービスが含まれています。ただし、場合によっては、特定のサービスをカスタマイズするか、独自のサービスを作成する必要があります。追跡サービスでは、処理情報をログ ファイルや SQL Server データベースなどのストレージ メディアに保存できます。このトピックでは、カスタム追跡サービスの作成に必要な手順を詳しく説明します。

カスタム追跡サービス クラスの作成

追跡データを受け取るコンポーネントは、すべて TrackingService 基本クラスから派生する必要があります。ホストは、追跡サービスを他の Windows Workflow Foundation サービスと同様に、Windows Workflow Foundation ランタイムに登録します。追跡サービスが登録されると、追跡フレームワークはサービスを認識し、ワークフロー インスタンスの実行の追跡を許可します。サービスの登録方法の詳細については、「方法 : ワークフロー サービスを追加または削除する」を参照してください。

カスタム追跡サービスは、TrackingService 抽象クラスから派生するクラス オブジェクトです。TrackingService クラスには、カスタム追跡サービスの動作を提供するためにオーバーライドする必要のある抽象メソッドがいくつか格納されています。

たとえば、追跡情報を出力するためにシステム イベント ログを使用するカスタム追跡サービスを作成するとします。開始するには、新しいクラスをプロジェクト内に作成し、EventLogTrackingService という名前にします。このクラスは、TrackingService 基本クラスから派生させます。

抽象基本クラスのメソッドをオーバーライドするのに必要なメソッドを生成するには、TrackingService クラス名を右クリックし、ショートカット メニューで [Implement abstract class 'TrackingService'] を選択します。これにより、カスタム追跡サービスを実装するために使用するメソッドの定義が生成されます。

コードは次のコード例のようになります。

using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Workflow.ComponentModel;
using System.Workflow.Runtime;
using System.Workflow.Runtime.Tracking;

namespace CustomTrackingService
{
    public class EventLogTrackingService : TrackingService
    {
        protected override TrackingProfile GetProfile(Guid workflowInstanceId)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        protected override TrackingProfile GetProfile(Type workflowType, Version profileVersionId)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        protected override TrackingChannel GetTrackingChannel(TrackingParameters parameters)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        protected override bool TryGetProfile(Type workflowType, out TrackingProfile profile)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        protected override bool TryReloadProfile(Type workflowType, Guid workflowInstanceId, out TrackingProfile profile)
        {
            throw new Exception("The method or operation is not implemented.");
        }
    }
}
Imports System
Imports System.Diagnostics
Imports System.Collections.Generic
Imports System.Text
Imports System.Threading
Imports System.Workflow.ComponentModel
Imports System.Workflow.Runtime
Imports System.Workflow.Runtime.Tracking

Public Class EventLogTrackingService
    Inherits TrackingService

    Protected Overloads Overrides Function GetProfile(ByVal workflowInstanceId As System.Guid) As System.Workflow.Runtime.Tracking.TrackingProfile

    End Function

    Protected Overloads Overrides Function GetProfile(ByVal workflowType As System.Type, ByVal profileVersionId As System.Version) As System.Workflow.Runtime.Tracking.TrackingProfile

    End Function

    Protected Overrides Function GetTrackingChannel(ByVal parameters As System.Workflow.Runtime.Tracking.TrackingParameters) As System.Workflow.Runtime.Tracking.TrackingChannel

    End Function

    Protected Overrides Function TryGetProfile(ByVal workflowType As System.Type, ByRef profile As System.Workflow.Runtime.Tracking.TrackingProfile) As Boolean
    End Function

    Protected Overrides Function TryReloadProfile(ByVal workflowType As System.Type, ByVal workflowInstanceId As System.Guid, ByRef profile As System.Workflow.Runtime.Tracking.TrackingProfile) As Boolean

    End Function
End Class

追跡プロファイル

TrackingService 基本クラスからオーバーライドする必要がある抽象メソッドには、TrackingProfiles と TrackingChannels の処理が含まれます。TrackingProfiles の使用方法の詳細については、「追跡プロファイルの作成と使用」を参照してください。TrackingService クラスの詳細については、TrackingService のトピックを参照してください。

追跡サービスに追跡データを転送するためにチャネルを開く前に、プロファイルを提供する必要があります。このプロファイルでは、追跡サービスがランタイム エンジンから受け取る追跡データの型を記述します。記述するには、新しい TrackingProfile オブジェクトを作成し、プロファイルを ActivityTrackPoint オブジェクト、および ActivityTrackingLocation オブジェクトと関連付けます。ワークフロー ランタイム エンジンは、次の例に示すように、オブジェクトの TryGetProfile メソッドを呼び出して、ワークフロー型を追跡プロファイルと関連付けます。この例では、GetDefaultProfile 1 つの静的メソッドを使用して既定の追跡プロファイルを作成しています。

Noteメモ :

GetProfile メソッドを呼び出すときは、メソッドに渡すバージョン番号が、使用する追跡プロファイルのバージョン番号と対応している必要があります。また、追跡プロファイルのバージョン番号と、SqlTrackingService サービスと共に使用されるストアド プロシージャ UpdateTrackingProfile のバージョン番号が同じであることが必要です。

Noteメモ :

GetTrackingChannel メソッドの実装例は、次のセクションの末尾にあります。

// Add in a local variable and overloaded constructor methods.
protected WorkflowRuntime runtimeContainer = null;
public EventLogTrackingService()
{
}

public EventLogTrackingService (WorkflowRuntime container)
{
    runtimeContainer = container;
}

// Implement the TrackingService abstract methods.
protected override TrackingProfile GetProfile(Guid workflowInstanceId)
{
    // Instance profiles not implemented.
    throw new NotImplementedException("The method or operation is not implemented.");
}

protected override TrackingProfile GetProfile(Type workflowType, Version profileVersionId)
{
    return GetDefaultProfile();
}

protected override bool TryGetProfile(Type workflowType, out TrackingProfile profile)
{
    // Depending on the workflowType, service can return different 
    // tracking profiles. In this sample, the same profile is returned 
    // for all running types.
    profile = GetDefaultProfile();
    return true;
}

protected override bool TryReloadProfile(Type workflowType, Guid workflowInstanceId, out TrackingProfile profile)
{
    // Reloading profiles not implemented.
    profile = null;
    return false;
}

// Create the profile.
private static TrackingProfile GetDefaultProfile()
{
    TrackingProfile profile = new TrackingProfile();
    profile.Version = new Version("3.0.0");

    // Add activity track points.
    ActivityTrackPoint atp = new ActivityTrackPoint();
    ActivityTrackingLocation location = new ActivityTrackingLocation(typeof(Activity));
    location.MatchDerivedTypes = true;
    foreach (ActivityExecutionStatus s in Enum.GetValues(typeof(ActivityExecutionStatus)))
    {
        location.ExecutionStatusEvents.Add(s);
    }
    atp.MatchingLocations.Add(location);
    profile.ActivityTrackPoints.Add(atp);

    // Add instance track points.
    WorkflowTrackPoint wtp = new WorkflowTrackPoint();
    WorkflowTrackingLocation workflowLocation = new WorkflowTrackingLocation();
    wtp.MatchingLocation = workflowLocation;

    foreach (TrackingWorkflowEvent workflowEvent in Enum.GetValues(typeof(TrackingWorkflowEvent)))
    {
        wtp.MatchingLocation.Events.Add(workflowEvent);
    }
    profile.WorkflowTrackPoints.Add(wtp);

    return profile;
}
' Add in a local variable and overloaded constructor methods.
Protected runtimeContainer As WorkflowRuntime = Nothing

Public Sub New()
End Sub

Public Sub New(ByVal container As WorkflowRuntime)
        runtimeContainer = container
End Sub

' Implement the TrackingService abstract methods.
Protected Overloads Overrides Function GetProfile(ByVal workflowInstanceId As Guid) As TrackingProfile
    ' Instance profiles not implemented
    Throw New NotImplementedException("The method or operation is not implemented.")
End Function

Protected Overloads Overrides Function GetProfile(ByVal workflowType As Type, ByVal profileVersionId As Version) As TrackingProfile
    Return GetDefaultProfile()
End Function

Protected Overrides Function TryGetProfile(ByVal workflowType As Type, ByRef profile As TrackingProfile) As Boolean
    ' Depending on the workflowType, service can return different 
    ' tracking profiles. In this sample, the same profile is returned 
    ' for all running types.
    profile = GetDefaultProfile()
    Return True
End Function

Protected Overrides Function TryReloadProfile(ByVal workflowType As Type, ByVal workflowInstanceId As Guid, ByRef profile As TrackingProfile) As Boolean
    ' Reloading profiles not implemented.
    profile = Nothing
    Return False
End Function

' Create the profile.
Private Shared Function GetDefaultProfile() As TrackingProfile
    Dim profile As New TrackingProfile()
    profile.Version = New Version("3.0.0")

    ' Add activity track points.
    Dim atp As New ActivityTrackPoint()
    Dim location As New ActivityTrackingLocation(GetType(Activity))
    location.MatchDerivedTypes = True
    Dim s As ActivityExecutionStatus
    For Each s In System.Enum.GetValues(GetType(ActivityExecutionStatus))
        location.ExecutionStatusEvents.Add(s)
    Next s
    atp.MatchingLocations.Add(location)
    profile.ActivityTrackPoints.Add(atp)

    ' Add instance track points.
    Dim wtp As New WorkflowTrackPoint()
    Dim workflowLocation As New WorkflowTrackingLocation()
    wtp.MatchingLocation = workflowLocation

    Dim workflowEvent As TrackingWorkflowEvent
    For Each workflowEvent In System.Enum.GetValues(GetType(TrackingWorkflowEvent))
        wtp.MatchingLocation.Events.Add(workflowEvent)
    Next workflowEvent
    profile.WorkflowTrackPoints.Add(wtp)
    Return profile
End Function

TrackingChannel の実装

TrackingChannel 抽象クラスは、1 つのワークフロー インスタンスの追跡イベントとデータを受け取る経路として機能します。TrackingChannel の目的は、追跡サービスの作成者が、スレッド セーフについて考慮することなく追跡情報を受け取ることができる機構を提供することです。各ワークフロー インスタンスが持つことができる実行スレッドは 1 つだけなので、TrackingChannel オブジェクトでは、一度に複数のスレッドがアクティブになることはありません。これにより、データ同期の必要性が軽減されます。

TrackingChannel は、ワークフローと追跡サービスの通信に使用されるオブジェクトです。EventLogTrackingService のための TrackingChannel を作成するには、基本クラス TrackingChannel から派生する EventLogTrackingChannel クラスを作成し、前のセクションで TrackingService 抽象クラスについて行ったのと同様に、必要な抽象メソッドを実装します。

ワークフローが追跡情報を送信する場合は、TrackingChannel クラスに定義された Send メソッドを介して行われます。パラメータとして渡される TrackingRecord から、追跡情報を抽出できます。ActivityRecord パラメータからデータを抽出し、抽出した情報をイベント ログに出力する方法を、次のコード例に示します。

public class EventLogTrackingChannel : TrackingChannel
{
    // Add in a local variable and constructor method.
    private TrackingParameters parameters = null;

    public EventLogTrackingChannel(TrackingParameters parameters)
    {
        this.parameters = parameters;
    }

    // InstanceCompletedOrTerminated is called by Tracking runtime to 
    // indicate that the Workflow instance finished running.
    protected override void InstanceCompletedOrTerminated()
    {
        System.Diagnostics.EventLog.WriteEntry("EventLogTrackingService", "Workflow Instance Completed or Terminated");
    }

    // Implement the TrackingChannel abstract methods.
    protected override void Send(TrackingRecord record)
    {
        if (record is ActivityTrackingRecord)
        {
            ActivityTrackingRecord act = (ActivityTrackingRecord)record;

            System.Diagnostics.EventLog.WriteEntry("EventLogTrackingService", "Activity: " + act.QualifiedName + " - " +  act.ExecutionStatus );
        }
        else if (record is WorkflowTrackingRecord)
        {
            if (TrackingWorkflowEvent.Changed == ((WorkflowTrackingRecord)record).TrackingWorkflowEvent)
            {
                System.Diagnostics.EventLog.WriteEntry("EventLogTrackingService", "Workflow changes have been applied");
            }
        }
    }
}
Public Class EventLogTrackingChannel
    Inherits TrackingChannel

    ' Add in a local variable and constructor method.
    Private parameters As TrackingParameters = Nothing

    Public Sub New(ByVal parameters As TrackingParameters)
        Me.parameters = parameters
    End Sub

    ' InstanceCompletedOrTerminated is called by Tracking runtime to 
    ' indicate that the Workflow instance finished running.
    Protected Overrides Sub InstanceCompletedOrTerminated()
        System.Diagnostics.EventLog.WriteEntry("EventLogTrackingService", "Workflow Instance Completed or Terminated")
    End Sub

    ' Implement the TrackingChannel abstract methods.
    Protected Overrides Sub Send(ByVal record As System.Workflow.Runtime.Tracking.TrackingRecord)
        If TypeOf record Is ActivityTrackingRecord Then
            Dim act As ActivityTrackingRecord = CType(record, ActivityTrackingRecord)
            System.Diagnostics.EventLog.WriteEntry("EventLogTrackingService", "Activity: " & act.QualifiedName & " - " & act.ExecutionStatus)
        ElseIf TypeOf record Is WorkflowTrackingRecord Then
            If TrackingWorkflowEvent.Changed = CType(record, WorkflowTrackingRecord).TrackingWorkflowEvent Then
                System.Diagnostics.EventLog.WriteEntry("EventLogTrackingService", "Workflow changes have been applied")
            End If
        End If
    End Sub
End Class

ワークフロー ランタイム エンジンは、EventLogTrackingService クラスに定義されている GetTrackingChannel メソッドを呼び出して、EventLogTrackingChannel への参照を取得します。次のコード例に示すように、新しい EventLogTrackingChannel オブジェクトを作成し、このオブジェクトを GetTrackingChannel メソッドから返します。

protected override TrackingChannel GetTrackingChannel(TrackingParameters parameters)
{
    return new EventLogTrackingChannel(parameters);
}
Protected Overrides Function GetTrackingChannel(ByVal parameters As TrackingParameters) As TrackingChannel
    Return New EventLogTrackingChannel(parameters)
End Function

関連項目

参照

TrackingService
TrackingChannel
TrackingProfile

概念

方法 : ワークフロー サービスを追加または削除する
追跡プロファイルの作成と使用

その他の技術情報

ConsoleTrackingService Sample
Tracking Profile Designer Sample
Windows Workflow Foundation Service の開発

Footer image

Copyright © 2007 by Microsoft Corporation.All rights reserved.