Creare servizi di rilevamento personalizzati
Windows Workflow Foundation contiene molti servizi che è possibile collegare all'ambiente host e cominciare ad utilizzare immediatamente. In alcune istanze, tuttavia, è necessario personalizzare un particolare servizio o crearne uno su misura. I servizi di rilevamento consentono di salvare in modo permanente informazioni sui processi in un supporto di archiviazione, inclusi elementi come file di log o database SQL Server. Questo argomento descrive i passaggi necessari per creare un servizio di rilevamento personalizzato.
Creazione della classe del servizio del rilevamento personalizzato
Ogni componente che riceve dati di rilevamento deve derivare dalla classe di base TrackingService. L'host registra servizi di rilevamento con il runtime di Windows Workflow Foundation come qualsiasi altro servizio di Windows Workflow Foundation. Dopo la registrazione di un servizio di rilevamento, il framework di rilevamento lo riconosce e gli consente di registrare l'esecuzione delle istanze del flusso di lavoro. Per ulteriori informazioni sulle modalità di registrazione dei servizi, vedere Procedura: aggiungere e rimuovere servizi del flusso di lavoro.
Un servizio di rilevamento personalizzato è un oggetto di classe che deriva dalla classe astrattaTrackingService. La classe TrackingService contiene molti metodi astratti che è necessario ignorare per stabilire il comportamento del servizio di rilevamento personalizzato.
Per esempio, supporre di voler creare un servizio di rilevamento personalizzato che utilizza il registro eventi di sistema per restituire informazioni di rilevamento. Per iniziare, creare una nuova classe nel progetto e denominarla EventLogTrackingService. Derivare la classe dalla classe baseTrackingService.
Per generare i metodi necessari per eseguire l'override dei metodi della classe di base astratta, fare clic con il pulsante destro del mouse sul nome della classe TrackingService e selezionare Implementa classe astratta 'TrackingService' nel menu di scelta rapida. Genera le definizioni del metodo che si utilizzano per implementare il servizio di rilevamento personalizzato.
Il codice dovrebbe risultare simile al seguente esempio di codice:
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
Profili di rilevamento
I metodi astratti dalla classe di base TrackingService che è necessario ignorare sono TrackingProfiles e TrackingChannels. Per ulteriori informazioni sulle modalità di utilizzo di TrackingProfiles, vedere Creazione e utilizzo di profili di rilevamento. Per ulteriori informazioni sulla classe TrackingService, vedere TrackingService.
Prima che venga aperto un canale per la trasmissione di dati di rilevamento al servizio di rilevamento, è necessario fornire un profilo. Il profilo descrive il tipo di dati di rilevamento che il servizio di rilevamento deve ricevere dal motore di runtime. A questo scopo, creare un nuovo oggetto TrackingProfile e associare il profilo agli oggetti ActivityTrackPoint e ActivityTrackingLocation. Il motore di runtime del flusso di lavoro assocerà tipi di flusso di lavoro ai profili di rilevamento chiamando il metodo TryGetProfile dell'oggetto, come mostra l'esempio seguente. In questo esempio, viene utilizzato un solo metodo statico denominato GetDefaultProfile per creare un profilo di rilevamento predefinito.
Nota
Quando si chiama il metodo GetProfile, il numero di versione che si passa nel metodo deve corrispondere al numero di versione del profilo di rilevamento che si desidera utilizzare. Inoltre, il numero di versione del profilo di rilevamento e della stored procedure UpdateTrackingProfile utilizzati con il servizio SqlTrackingService devono corrispondere.
Nota
L'implementazione di esempio per il metodo GetTrackingChannel viene fornita alla fine della prossima sezione.
// 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
Implementazione di TrackingChannel
La classe astratta TrackingChannel serve da condotto per ricevere eventi di rilevamento e dati per una sola istanza del flusso di lavoro. Lo scopo di TrackingChannel è fornire un meccanismo affinché i writer del servizio di rilevamento ricevano informazioni di rilevamento senza dovere considerare la protezione dei thread. Poiché ogni istanza del flusso di lavoro ha solo uno thread di esecuzione, non c'è mai più di un thread attivo in un oggetto TrackingChannel. Ciò riduce la necessità di sincronizzare i dati.
TrackingChannel è l'oggetto utilizzato per la comunicazione tra il flusso di lavoro e il servizio di rilevamento. Per creare un oggetto TrackingChannel per EventLogTrackingService, creare una classe EventLogTrackingChannel, dedurre la classe dalla classe di base TrackingChannel e implementare i metodi astratti obbligatori come effettuato per la classe astratta TrackingService nella sezione precedente.
Quando un flusso di lavoro invia informazioni di rilevamento, lo fa tramite il metodo Send definito nella classe TrackingChannel. Una classe TrackingRecord è passata come parametro dal quale è possibile estrarre le informazioni di rilevamento. Nell'esempio di codice seguente viene illustrato come estrarre dati dal parametro ActivityRecord e restituire le informazioni al registro eventi.
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
Il motore di runtime del flusso di lavoro ottiene un riferimento per EventLogTrackingChannel chiamando il metodo GetTrackingChannel definito nella classe EventLogTrackingService. Creare un nuovo oggetto EventLogTrackingChannel e restituire l'oggetto dal metodo GetTrackingChannel come mostra l'esempio di codice seguente.
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
Vedere anche
Riferimenti
TrackingService
TrackingChannel
TrackingProfile
Concetti
Procedura: aggiungere e rimuovere servizi del flusso di lavoro
Creazione e utilizzo di profili di rilevamento
Altre risorse
ConsoleTrackingService Sample
Tracking Profile Designer Sample
Sviluppo dei servizi di Windows Workflow Foundation
Copyright © 2007 Microsoft Corporation. Tutti i diritti riservati.