建立自訂追蹤服務
Windows Workflow Foundation 包含數個您可以插入您的裝載環境及立刻開始使用的數個服務。 在某些執行個體中,您可能必須自訂特定服務或建立您自己的服務。 追蹤服務可讓您將處理序資訊保存至儲存媒體中,包括如記錄檔或 SQL Server 資料庫等。 這個主題詳細說明建立您自己的自訂追蹤服務所需的步驟。
建立自訂追蹤服務類別
接收追蹤資料的每個元件必須衍生自 TrackingService 基底類別。 主機以就像任何其他 Windows Workflow Foundation 服務的 Windows Workflow Foundation 執行階段來註冊追蹤服務。 註冊追蹤服務後,追蹤架構辨識它並允許它追蹤工作流程執行個體的執行。 如需如何註冊服務的詳細資訊,請參閱HOW TO:新增和移除工作流程服務。
自訂追蹤服務是一種衍生自抽象 TrackingService 類別的類別物件。 TrackingService 類別包含數個抽象方法,您必須覆寫這些方法以提供您的自訂追蹤服務行為。
舉例來說,假設您要建立使用系統事件記錄的自訂追蹤服務來輸出追蹤資訊。 若要開始,請在您的專案中建立新類別,並將它命名為 EventLogTrackingService。 將類別衍生自 TrackingService 基底類別。
若要產生覆寫抽象基底類別方法所需的方法,請在 TrackingService 類別名稱上按一下滑鼠右鍵,然後在捷徑功能表中選取 [實作抽象類別 '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 的單一靜態方法建立預設的追蹤設定檔。
注意
當您呼叫 GetProfile 方法時,您傳遞至方法的版本號碼必須對應您想要使用的追蹤設定檔的版本號碼。 此外,追蹤設定檔與配合 SqlTrackingService 服務使用的 UpdateTrackingProfile 預存程序之間的版本號碼必須相符。
注意
在下一個區段的結尾提供 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 抽象類別可當做接收單一工作流程執行個體之追蹤事件和資料的管道。 TrackingChannel 的目的是為追蹤服務寫入器提供接收追蹤資訊的機制,而且又不必考量執行緒的安全性。 由於每個工作流程執行個體只有一個執行的執行緒,因此在 TrackingChannel 物件中從來不會一次啟用一個以上的執行緒。 這樣可減少資料同步化的需求。
TrackingChannel 是工作流程和您的追蹤服務之間通訊所用的物件。 若要建立 EventLogTrackingService 的 TrackingChannel,請建立 EventLogTrackingChannel 類別,從 TrackingChannel 基底類別衍生類別,並以您在先前區段中為 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 服務
Copyright © 2007 by Microsoft Corporation. All rights reserved.