Erstellen von benutzerdefinierten Überwachungsdiensten

Windows Workflow Foundation beinhaltet mehrere Dienste, die mit der Hostumgebung kompatibel und umgehend verwendbar sind. In einigen Instanzen muss jedoch möglicherweise ein bestimmter Dienst angepasst oder ein eigener Dienst erstellt werden. Überwachungsdienste ermöglichen das Speichern von Prozessinformationen auf einem Speichermedium. Zu diesen Informationen zählen Protokolldateien oder eine SQL Server-Datenbank. In diesem Thema werden detailliert die Schritte aufgeführt, die zum Erstellen Ihres eigenen angepassten Überwachungsdiensts erforderlich sind.

Erstellen der benutzerdefinierten Überwachungsdienstklasse

Jede Komponente, die Überwachungsdaten empfängt, muss von der TrackingService-Basisklasse abgeleitet werden. Der Host registriert Überwachungsdienste bei der Windows Workflow Foundation-Laufzeit ebenso wie alle anderen Windows Workflow Foundation-Dienste. Nach dem Registrieren eines Überwachungsdiensts erkennt das Überwachungsframework den Dienst und gestattet ihm, die Ausführung der Workflowinstanz zu überwachen. Weitere Informationen zum Registrieren von Diensten finden Sie unter Gewusst wie: Hinzufügen und Entfernen von Workflowdiensten.

Ein benutzerdefinierter Überwachungsdienst ist ein Klassenobjekt, das von der abstrakten TrackingService-Klasse abgeleitet wird. Die TrackingService-Klasse beinhaltet mehrere abstrakte Methoden, die überschrieben werden müssen, um das Verhalten des benutzerdefinierten Überwachungsdiensts bereitzustellen.

Beispiel: Sie möchten einen benutzerdefinierten Überwachungsdienst erstellen, der das Systemereignisprotokoll zum Ausgeben von Überwachungsinformationen verwendet. Erstellen Sie zunächst eine neue Klasse im Projekt, und benennen Sie sie folgendermaßen: EventLogTrackingService. Leiten Sie die Klasse von der TrackingService-Basisklasse ab.

Wenn Sie die zum Überschreiben der Methoden der abstrakten Basisklasse erforderlichen Methoden generieren möchten, klicken Sie mit der rechten Maustaste auf den TrackingService-Klassennamen, und wählen Sie im Kontextmenü die Option für das Implementieren der abstrakten Klasse 'TrackingService' aus. Dadurch werden die Methodendefinitionen generiert, die Sie zum Implementieren des benutzerdefinierten Überwachungsdiensts verwenden.

Der Code sollte ungefähr wie im folgenden Codebeispiel aussehen:

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

Überwachungsprofile

Die abstrakten Methoden, die von der TrackingService-Basisklasse überschrieben werden müssen, beinhalten das Arbeiten mit TrackingProfiles und TrackingChannels. Weitere Informationen zur Verwendung von TrackingProfiles finden Sie unter Erstellen und Verwenden von Überwachungsprofilen. Weitere Informationen zur TrackingService-Klasse finden Sie unter TrackingService.

Vor dem Öffnen eines Kanals für die Übertragung von Überwachungsdiensten muss ein Profil bereitgestellt werden. Dieses Profil beschreibt die Art der Überwachungsdaten, die der Überwachungsdienst vom Laufzeitmodul empfangen möchte. Erstellen Sie dazu ein neues TrackingProfile-Objekt, und weisen Sie das Profil dem ActivityTrackPoint-Objekt und dem ActivityTrackingLocation-Objekt zu. Dieses Workflow-Laufzeitmodul ordnet Workflowtypen Überwachungsprofile durch Aufrufen der TryGetProfile-Methode des Objekts zu (siehe folgendes Beispiel). In diesem Beispiel wird eine einzelne statische Methode mit der Bezeichnung GetDefaultProfile verwendet, um ein Standardverfolgungsprofil zu erstellen.

Hinweis

Beim Aufrufen der GetProfile-Methode muss die Versionsnummer, die an die Methode übergeben wird, der Versionsnummer des gewünschten Überwachungsprofils entsprechen. Zudem muss die Versionsnummer zwischen dem Überwachungsprofil und der gespeicherten UpdateTrackingProfile-Prozedur übereinstimmen, die mit dem SqlTrackingService-Dienst verwendet wird.

Hinweis

Die Beispielimplementierung für die GetTrackingChannel-Methode finden Sie am Ende des nächsten Abschnitts.

// 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

Implementieren des TrackingChannel

Die abstrakte TrackingChannel-Klasse dient als Kanal, in dem Überewachungsereignisse und Daten für eine einzelne Workflowinstanz empfangen werden. Der Zweck von TrackingChannel ist das Bereitstellen eines Mechanismus für Überwachungsdienstwriter, um Überwachungsinformationen ohne Berücksichtigung der Threadsicherheit zu empfangen. Da jede Workflowinstanz nur über einen Ausführungsthread verfügt, ist in einem TrackingChannel -Objekt jeweils nur ein Thread aktiv. Dadurch sind weniger Datensynchronisierungen erforderlich.

TrackingChannel ist das Objekt, das für die Kommunikation zwischen dem Workflow und dem Überwachungsdienst verwendet wird. Wenn Sie TrackingChannel für EventLogTrackingService erstellen möchten, erstellen Sie eine EventLogTrackingChannel-Klasse, leiten Sie die Klasse von der TrackingChannel-Basisklasse ab, und implementieren Sie die erforderlichen abstrakten Methoden ebenso wie für die abstrakte TrackingService-Klasse im vorherigen Abschnitt.

Sendet ein Workflow Überwachungsinformationen, geschieht dies mit der in der TrackingChannel-Klasse definierten Send-Methode. TrackingRecord wird als Parameter übergeben, aus dem Sie die Überwachungsinformationen extrahieren können. Im folgenden Codebeispiel wird gezeigt, wie Daten aus dem ActivityRecord-Parameter extrahiert und die Informationen in das Ereignisprotokoll ausgegeben werden.

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

Das Workflow-Laufzeitmodul ruft einen Verweis für EventLogTrackingChannel ab, indem die in der EventLogTrackingService-Klasse definierte GetTrackingChannel-Methode aufgerufen wird. Erstellen Sie ein neues EventLogTrackingChannel-Objekt, und geben Sie dieses Objekt von der GetTrackingChannel-Methode gemäß der Darstellung im folgenden Codebeispiel zurück.

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

Siehe auch

Referenz

TrackingService
TrackingChannel
TrackingProfile

Konzepte

Gewusst wie: Hinzufügen und Entfernen von Workflowdiensten
Erstellen und Verwenden von Überwachungsprofilen

Weitere Ressourcen

ConsoleTrackingService Sample
Tracking Profile Designer Sample
Entwickeln von Windows Workflow Foundation-Diensten

Footer image

Copyright © 2007 by Microsoft Corporation. Alle Rechte vorbehalten.