程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> Windows Workflow Foundation中的跟蹤服務

Windows Workflow Foundation中的跟蹤服務

編輯:關於.NET

目錄

跟蹤體系結構

跟蹤配置文件

SQL 跟蹤服務

查詢跟蹤數據

自定義跟蹤服務

Windows Workflow Foundation 中最強大的功能之一是跟蹤。它使您能夠監控事件、活動屬性以及您的工作流中的自定義數據。在本專欄中,我將檢查跟蹤基礎結構、向您介紹如何使用內置的基於 SQL Server™ 的跟蹤服務以及如何為各種應用創建自定義跟蹤服務。順著這一思路,我將演示如何使用所跟蹤的信息以及如何通過使用跟蹤來滿足一些常見的需求。

許多應用程序需要了解程序邏輯和處理步驟的執行。這有助於企業遵守法規,根據執行裡程碑或各種其他原因來管理風險列表。Windows® Workflow Foundation 提供了靈活的基礎結構,您可以在其中覆蓋您的自定義實現,而不必為各應用程序創建不同的跟蹤系統。這簡化了開發模型,使您可以關注於跟蹤的業務要求。

跟蹤體系結構

當在 Windows Workflow Foundation 中承載工作流時,您既可以承載工作流運行庫,也可以承載一組運行時服務。許多運行時服務(如持久性服務)必須最多有一個在運行庫中注冊的實例。跟蹤服務是個例外,允許將多個跟蹤服務添加到運行庫中以支持不同的業務要求。這使您能夠將若干不同的跟蹤任務應用於一個應用程序,各跟蹤服務負責特定的實現。

Windows Workflow Foundation 中的跟蹤基於中央偵聽器,偵聽器可監控活動和工作流事件並將相應的數據發送到各個配置的跟蹤服務。(這種體系結構如圖 1 所示。)跟蹤偵聽器接收所有事件的通知,但多數情況下,只有這些事件中的一個子集是有用的。而且,如果您要使用多個跟蹤服務,各任務有可能將只關注於唯一一個信息子集。因此,跟蹤偵聽器將查詢各配置的跟蹤服務以跟蹤各類工作流的配置文件。

圖 1跟蹤體系結構

跟蹤配置文件為偵聽器提供關於跟蹤服務要接收的事件的類型的信息。這些事件可以分為三類:工作流、活動和用戶。

工作流事件使您能夠跟蹤工作流可能處於的各種狀態,以及它們發生的時間。對於包含自定義事件參數的事件,如 WorkflowTerminated 或 WorkflowCompleted,事件參數本身可被跟蹤,並隨後被查詢。

活動事件使您能夠跟蹤活動進入特定狀態的時間和活動進入該狀態時具體的活動屬性值。例如,如果您有一個發送電子郵件的活動,當活動進入 Closed 狀態時,您可以跟蹤 To 地址屬性。

最後,用戶事件使您可以在您的工作流或活動中手動跟蹤數據。

跟蹤配置文件

每個跟蹤服務都必須向跟蹤偵聽器提供跟蹤配置文件。一個服務可以為所有工作流提供相同的配置文件,也可以為不同類型的工作流提供不同的配置文件。由服務編寫者確定管理和生成配置文件的方式。

可使用在 System.Workflow.Runtime.Tracking 命名空間中或直接在 XML 中找到的對象模型來創建跟蹤配置文件。通常使用對象模型來創建它們,但這不是表示配置文件的唯一方法,也並非最佳方法。因此,跟蹤配置文件可被序列化到 XML,也可以從 XML 反序列化。您可以使用 TrackingProfileSerializer 類將 TrackingProfile 對象轉換為 XML 文本,反之亦然。Windows SDK 中的 Tracking Profile Designer(跟蹤配置文件設計器)示例是與此有關的一個有用示例,也是基本跟蹤配置文件編輯的一個不錯工具。該應用程序使您能夠使用工作流設計圖面可視化地定義跟蹤配置文件。盡管該工具有一些局限性,如缺乏對用戶跟蹤點的支持,但它可使您查看序列化形式的跟蹤文件。在許多情形下,它還可加快開發和部署跟蹤配置文件的速度。

跟蹤配置文件實質上是一組跟蹤點。各跟蹤點與被跟蹤的事件的類型相關,為運行庫提供了關於何時提取數據以及提取哪些數據的信息。例如,要指明應跟蹤的工作流事件,WorkflowTrackPoint 必須被添加到跟蹤配置文件中。跟蹤點包含一個或多個跟蹤位置,這些跟蹤位置實際定義了跟蹤數據的位置和時間。例如,在 WorkflowTrackPoint 中,MatchingLocation 屬性可識別各種要跟蹤的工作流事件。圖 2 中的代碼顯示了要創建的跟蹤配置文件。它有一個 WorkflowTrackPoint,指明了服務要跟蹤失敗條件(如異常、終止和工作流終止)。

Figure2工作流 TrackPoint

//create the profile object and set the version
TrackingProfile profile = new TrackingProfile();
profile.Version = new Version(1, 0, 0);
//define a tracking point
WorkflowTrackPoint wfTrack = new WorkflowTrackPoint();
//create a list of events we are interested in
List<TrackingWorkflowEvent> events = new List<TrackingWorkflowEvent>();
events.Add(TrackingWorkflowEvent.Aborted);
events.Add(TrackingWorkflowEvent.Terminated);
events.Add(TrackingWorkflowEvent.Exception);
//create a tracking location to indicate which events should be tracked
WorkflowTrackingLocation wfLocation =
  new WorkflowTrackingLocation(events);
//set the matching location on the track point
wfTrack.MatchingLocation = wfLocation;
//add the track point to the profile
profile.WorkflowTrackPoints.Add(wfTrack);

ActivityTrackPoint 支持更豐富的跟蹤。由於活動構成了工作流的核心,因此這是符合邏輯的。ActivityTrackPoint 包含 MatchingLocations 和 ExcludedLocations 集合,使您能夠密切控制數據收集的時間。對於上述兩個集合,您可以定義代表您要匹配的條件集合的 ActivityTrackingLocation。

ActivityTrackingLocation 類使您能夠定義您要根據其類型進行跟蹤的活動。您還可以指明您是否要匹配派生的活動。例如,如果您要匹配所有活動,則應當使用 System.ComponentModel.Activity 類型並將 MatchDerivedTypes 設置為 True。這樣就能匹配所有基礎活動類以及由其派生的所有活動。您還可以將此信息添加到 ActivityTrackPoint 的 MatchingLocations 集合以指明您要跟蹤這些事件,或者將此信息添加到 ExcludedLocations 集合以指明該數據不應被收集。

為了進行更詳細的控制,您可以指定為跟蹤數據必須滿足的條件(以屬性等式的形式)。例如,您可能選擇僅當 SendEmail 活動的優先級屬性設置為 High 時才跟蹤電子郵件。圖 3 顯示了這樣一個示例。

Figure3ActivityTrackPoint

ActivityTrackPoint actTrack = new ActivityTrackPoint();
ActivityTrackingLocation actMatch = new ActivityTrackingLocation(
  typeof(SendEmail), false, new ActivityExecutionStatus[] {
    ActivityExecutionStatus.Closed });
ActivityTrackingCondition condition =
  new ActivityTrackingCondition("Priority", "High");
actMatch.Conditions.Add(condition);
actTrack.MatchingLocations.Add(actMatch);
profile.ActivityTrackPoints.Add(actTrack);

您還能夠以屬性值的形式從活動或工作流提取數據。例如,當在工作流中到達您的匹配位置時,您可以跟蹤 SendEmail 活動的 To 和 Subject 屬性。可以通過將 ActivityDataTrackingExtract 或 WorkflowDataTrackingExtract 項添加到 ActivityTrackPoint 的 Extracts 集合來實現此跟蹤。每個 ActivityDataTrackingExtract 都可識別要提取並發送到跟蹤服務的成員。將數據提取添加到活動跟蹤點,這樣被跟蹤的 To 和 Subject 屬性就如下所示:

actTrack.Extracts.Add(new ActivityDataTrackingExtract("To"));
actTrack.Extracts.Add(new ActivityDataTrackingExtract("Subject"));

三種類型中最靈活的是可以識別最後跟蹤點的 UserTrackPoint。有時,您需要跟蹤來自工作流但不可用作活動屬性的數據。或者可能需要使用 ActivityTrackingLocation 中簡單條件支持以外的邏輯。在這種情況下,您可以調用 ActivityExecutionContext 或 Activity 類中的 TrackData 方法。這使您可以將數據與數據項的可選密鑰或名稱發送到跟蹤偵聽器。對於接收該數據的跟蹤服務,必須定義具有正確匹配位置的 UserTrackPoint。您還可以定義工作流和活動數據提取,以便在 UserTrackPoint 匹配時跟蹤工作流或當前活動的屬性。

SQL 跟蹤服務

Windows Workflow Foundation 包括 SQL Server 跟蹤服務,該服務使您能夠定義某個工作流類型的跟蹤配置文件並將其部署到 SQL Server。在運行時,跟蹤服務使用該配置文件以配置跟蹤偵聽器。SQL Server 跟蹤服務包括幾個出色的功能,如配置文件版本管理、配置文件更新通知和數據劃分。

通過調用 UpdateTrackingProfile 存儲過程並在系列化配置文件中進行傳遞,可將跟蹤配置文件部署到 SQL 跟蹤服務,其中包括工作流類型信息和版本號。您可以使用此存儲過程來插入特定於您的工作流類型的跟蹤配置文件,但每次更新配置文件時您必須使用唯一的版本號。我前面所談到的 TrackingProfileSerializer 使您能夠獲得配置文件的 XML 文本,這樣,您就能將其傳遞到存儲過程。

如果您沒有為您的工作流類型指定跟蹤文件,SQL 跟蹤服務將使用 UseDefaultProfile 設置以確定它是否應為跟蹤偵聽器提供默認的配置文件。默認配置文件可跟蹤工作流的所有狀態事件和所有活動。它還包括匹配位置,以跟蹤所提交的任何用戶跟蹤事件。如果您不需要此默認行為,當配置 SQL 跟蹤服務時,則需要將 UseDefaultProfile 屬性設置為 False。只有指定了配置文件的那些工作流類型才被跟蹤。

為了確保跟蹤服務是最新的,跟蹤偵聽器會定期詢問各跟蹤服務所收到的配置文件。為了避免重復加載或創建跟蹤配置文件,跟蹤服務可以實現 IProfileNotification 接口。為此定義了兩種事件:ProfileUpdated 和 ProfileRemoved。當跟蹤服務實現此接口時,跟蹤偵聽器不會查詢更新配置文件信息,除非發生這些事件之一。為了支持此模型,SQL Server 跟蹤服務會定期查詢數據庫(默認情況下,每 60 秒查詢一次)以確定工作類型的跟蹤配置文件是否已被更新或刪除。您可以配置服務查詢更新的頻率,方法是將 ProfileChangeCheckInterval 屬性設置為表示輪詢之間微秒數的值。

由於在運行環境中,跟蹤數據可以迅速累積,SQL 跟蹤服務支持數據劃分。您可以通過配置來按天、周、月或年來劃分數據,服務將會為各時間段創建跟蹤表。另外,您可以控制是按需移動數據(這樣就可以為其預定停機時間),還是自動移動數據(當工作流完成時)。為了配置此設置,您要將 SQL Server 跟蹤服務的 PartitionOnCompletion 屬性設置為“true”,以指明各工作流完成時應被移動到相應的跟蹤分區。為了對數據進行手動分區,您可以調用跟蹤數據庫中的 PartitionCompletedWorkflowInstances 存儲過程。

查詢跟蹤數據

當您使用 SQL 跟蹤服務收集數據時,數據被存儲在 SQL Server 中,這意味著您可以使用傳統的報告工具查看數據和進行分析。但在某些情形下,您需要查詢應用程序中的工作流數據。您不必編寫 SQL 查詢和確定數據庫中的正確關系,Windows Workflow Foundation 包含了跟蹤查詢編程接口,使您能夠為工作流實例搜索跟蹤信息。該信息作為類返回,提供了對所有跟蹤的事件和您的跟蹤配置文件指定的數據的訪問。

SqlTrackingQuery 類使您既可以使用工作流的實例 ID 來嘗試加載特定工作流實例的跟蹤數據,也可以使用離散參數集來查詢工作流列表。當加載特定實例時,您使用 TryGetWorkflow 方法,該方法返回指明請求是否成功的布爾值。要查詢多個工作流,請使用 GetWorkflows 方法,該方法需要一個 SqlTrackingQueryOptions 實例。

查詢選項使您能夠定義在跟蹤數據庫中搜索工作流時要使用的參數。最簡單的選項包括最小和最大日期值以及工作流類型和狀態。例如,您可以配置選項以搜索所有與您的工作流類型匹配的工作流,工作流具有 Completed 狀態,日期位於當前日期和一周前的日期之間。這使您能夠檢索關於工作流類型和生成方式的目標信息。

我已經介紹了讓您指明所關注的失敗條件的跟蹤配置文件。使用圖 4 顯示的代碼,您可以在數據庫中查詢所有終止工作流的實例,並輸出異常詳細信息。請注意異常詳細信息被作為跟蹤的終止事件的事件參數包含在跟蹤信息中。

Figure4查詢終止的工作流實例

SqlTrackingQueryOptions options = new SqlTrackingQueryOptions();
options.WorkflowStatus = WorkflowStatus.Terminated;
SqlTrackingQuery query = new SqlTrackingQuery(connectionString);
IList<SqlTrackingWorkflowInstance> workflows =
  query.GetWorkflows(options);
foreach (SqlTrackingWorkflowInstance workflow in workflows)
{
  foreach(WorkflowTrackingRecord workflowEvent in
    workflow.WorkflowEvents)
  {
    TrackingWorkflowTerminatedEventArgs args =
      workflowEvent.EventArgs as
        TrackingWorkflowTerminatedEventArgs;
    if (args != null)
    {
      Console.WriteLine(
        "workflow {0} terminated with exception: {1}",
      workflow.WorkflowInstanceId, args.Exception.Message);
    }         
  }
}

您還可以根據提取的值進行搜索。例如,如果您配置了跟蹤配置文件以提取 SendEmail 活動的 To 地址,則可以編寫查詢以返回工作流實例,其中 To 地址與確定的值(如特定的員工或合作伙伴)相匹配。以下代碼是使用 SqlTrackingQueryOptions 中的 TrackingDataItemValue 項根據提取的值優化對特定項的搜索的示例:

SqlTrackingQueryOptions options = new SqlTrackingQueryOptions();
TrackingDataItemValue item = new TrackingDataItemValue(
  "sendEmail1", "To", "[email protected]");
options.TrackingDataItems.Add(item);
SqlTrackingQuery query = new SqlTrackingQuery(connectionString);
IList<SqlTrackingWorkflowInstance> workflows =
  query.GetWorkflows(options);

如果選擇直接查詢 SQL Server 數據庫以進行報告或執行其他操作,則應當使用在表中定義的視圖而不直接使用表。通常,這是一個不錯的做法,當視圖要包含來自所有已創建的跟蹤分區的數據時,尤為重要。通過使用視圖,不再需要自己合並所有這些表中的數據。

自定義跟蹤服務

跟蹤數據直至其進入 SQL Server 數據庫是一個重要用例,而且可能是最常見的用例,它不是使用跟蹤信息的唯一情形。因為它是一項通用要求,Microsoft 決定將這項豐富的服務包含在 Windows Workflow Foundation 中。然而,這類具有廣泛用途的服務必須盡可能通用。這意味著在許多情況下,它可能不適合。在這種情況下,您可以創建自定義跟蹤服務。

在工作流解決方案中有許多使用自定義跟蹤服務可滿足的要求。在此,我將討論創建您自己的跟蹤服務的基本知識,並提供一些符合通用要求的自定義服務的示例。需要記住的重要一點是跟蹤是您對工作流的監控。一旦理解了借助跟蹤配置文件配置跟蹤服務的方式,就可以獲得所需的結果,接下來就是自定義的服務應如何使用或表示跟蹤的信息。

為了創建自定義跟蹤服務,您需要完成兩件事情。首先,要確定如何為您的服務創建跟蹤配置文件。某些情況下,在所有工作流類型中,配置文件都可能是靜態的和不變的。在這種情況下,您可以在代碼中創建配置文件,當需要配置文件時,只需將其返回至運行庫即可。然而,如果您需要跟蹤服務支持多個配置文件或不同版本的配置文件,則需要一種存儲該信息和從您的跟蹤服務中檢索該信息的方法。

接下來,您要實現兩個提供您的服務的運行時行為的類:跟蹤服務和跟蹤通道。該跟蹤服務類作為工作流運行時服務,它是主機應用程序的直接接口和與您的跟蹤服務交互的運行庫。您要創建該類的實例並使用代碼或配置將其添加到工作流運行庫中,與任何其他服務一樣。

該跟蹤服務類有以下兩種主要功能:為跟蹤偵聽器提供跟蹤配置文件,並提供偵聽器可向其寫入數據的跟蹤通道。跟蹤通道是您實現的用於接收和處理跟蹤數據的類。它可以在存儲區域(如 SQL Server 或 Windows 事件日志)之外寫入該數據;可以為操作引發事件,如 Windows Management Instrumentation (WMI) 事件;還可以將數據發送回跟蹤服務以將其保存在內存中並使其可供主機應用程序使用。當然,還有其他一些選項,您使用數據的方式將取決於您的需求和要求。您的自定義跟蹤服務將按它們所使用的跟蹤配置文件以及它們處理所接收的數據的方式加以區分。

因為具有以下兩種簡單方法,所以跟蹤通道是最方便的起點:Send 和 InstanceCompletedOrTerminated。您的跟蹤服務應為各工作流實例提供跟蹤通道,為各請求提供跟蹤通道的唯一實例是一種通用做法。通常,您要提供將 TrackingParameters 作為參數的構造函數,在實現其他方法時您可能需要此信息。TrackingParameters 類有關於要被跟蹤的工作流實例(如實例 ID)、對根活動定義的訪問的信息,以及關於父活動和工作流調用(如果該工作流不是從其他工作流中調用的)的信息。

InstanceCompletedOrTerminated 方法使您能夠在活動完成時跟蹤服務以獲得通知,這樣它就能清除與跟蹤工作流相關的所有資源。通常,這需要按照 TrackingParameters 提供的內容訪問工作流實例 ID,因為 InstanceCompletedOrTerminated 方法不帶任何參數。

可為跟蹤配置文件中所請求的每一跟蹤記錄調用您的跟蹤通道的 Send 方法。與配置文件類似,也存在工作流、活動和由基類 TrackingRecord 派生的用戶跟蹤記錄。在 Send 方法中,您要檢查已提交了哪種類型的跟蹤記錄,然後進行相應地處理。例如,如果您知道您的跟蹤配置文件沒有指明所關注的用戶跟蹤事件,您就無需在您的跟蹤通道中處理用戶跟蹤記錄。

跟蹤服務類本身負責管理跟蹤配置文件。跟蹤服務基類提供了幾種檢索配置文件的方法,使您能夠根據工作流類型和工作流實例管理配置文件。這意味著您的服務可以返回相應的配置文件,范圍從對所有工作流都相同的配置文件到對各工作流實例是唯一的配置文件。

對於 GetProfile 方法,存在兩種重載。一種重載需要實例 ID,另一種重載需要類型和配置文件版本號。另外,TryGetProfile 也需要類型信息。在所有這些情況下,您的自定義跟蹤服務的工作就是返回與類型或實例相適應的跟蹤配置文件。

此外,還存在一種稱為 TryReloadProfile 的方法,如果存在更新的配置文件,該方法將進行運行時調用以獲得該文件。為了確保及時更新,跟蹤偵聽器要定期向您的跟蹤服務詢問以確定是否使用更新的配置文件。無需在每次需要時創建新的配置文件或查找配置文件,您可以在您的自定義跟蹤服務中實現 IProfileNotification 接口。IProfileNotifcation 接口包括以下兩種事件:ProfileUpdated 和 ProfileRemoved。當您在您的跟蹤服務中實現此接口時,跟蹤偵聽器不再進行更新輪詢。取而代之的是,在該接口的事件發生過程中它要等待所有更新的通知。

在本專欄的代碼下載中包含了幾個示例跟蹤服務。當前狀態示例使用跟蹤以獲得狀態機工作流的當前狀態,並使其可供主機應用程序使用。該服務的跟蹤配置文件包含針對 State 活動執行狀態的活動跟蹤點。當收到活動跟蹤記錄時,跟蹤通道會使用當前狀態名更新跟蹤服務類中的詞典。該示例是一個服務示例,對於所有工作流都有相同配置文件,並將數據寫回服務以便由主機應用程序查詢。

包含在代碼下載中的另一個示例跟蹤服務旨在解決 Windows Workflow Foundation 中開發人員常見的一種問題。考慮到工作流執行以及與主機應用程序分離方式的性質,獲得對運行工作流的引用和提取屬性值不是一個簡單過程。這是一個常見要求,特別是在 ASP.NET 情形中。一旦 ManualWorkflowScheduler 完成在工作流中執行相應步驟,可能需要使用工作流的屬性值更新用戶接口。

使用 CallExternalMethod 活動可傳遞工作流中的信息,但這並不總是一種理想的解決方案,而且在大型項目中被證明是難以承受的。工作流屬性跟蹤服務示例使用跟蹤來解決此問題。在此跟蹤服務中,對於每種工作流類型,返回的配置文件是不同的,以便反映工作流中的不同屬性。使用反射構建工作流數據跟蹤提取集合,並將它們添加到活動跟蹤點。跟蹤的位置位於各活動的 Closed 事件中。因此,當各活動結束後,來自工作流實例的屬性值將被提取,並發送到跟蹤通道。通道將更新服務中的詞典,使這些值可供主機應用程序使用。

這是兩個相當簡單的自定義跟蹤服務的示例,但二者均是針對開發人員常見情形,提供了簡單、可重復使用的實現,並充分利用了現有跟蹤基礎結構。如果缺乏構建基礎,這些挑戰將會更大,需要更多的自定義代碼,而解決方案也可能不一致。

正如您所看到的,Windows Workflow Foundation 中的跟蹤服務非常靈活,有助於應對大量不同的業務要求。跟蹤對於工作流的可視性至關重要,自定義跟蹤服務是您在應用程序中充分發揮這種可視性的“利器”。

本文配套源碼

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved