WF の仕組みとして TrackingRecord によるトラッキングの仕組みが用意されています。これはワークフローが、またはアクティビティが何か動作をするたびに通知されるレコードで、全部で 13 種類の状態が通知されます。各トラッキングレコードが何を伝えてくれるかは MSDN を参照してください。
TrackingRecord : WorkflowInstanceRecord { InstanceId = c0c010f2-d75e-4084-a697-16951fde0a57, RecordNumber = 0, EventTime = 2011/05/02 9:59:55, ActivityDefinitionId = Sequence, State = Started }
TrackingRecord : ActivityStateRecord { InstanceId = c0c010f2-d75e-4084-a697-16951fde0a57, RecordNumber = 1, EventTime = 2011/05/02 9:59:55, Activity { Name=Sequence, ActivityId = 1, ActivityInstanceId = 1, TypeName=System.Activities.Statements.Sequence }, State = Executing }
TrackingRecord : ActivityStateRecord { InstanceId = c0c010f2-d75e-4084-a697-16951fde0a57, RecordNumber = 2, EventTime = 2011/05/02 9:59:56, Activity { Name=Assign, ActivityId = 7, ActivityInstanceId = 2, TypeName=System.Activities.Statements.Assign }, State = Executing }
TrackingRecord : ActivityStateRecord { InstanceId = c0c010f2-d75e-4084-a697-16951fde0a57, RecordNumber = 3, EventTime = 2011/05/02 9:59:56, Activity { Name=Assign, ActivityId = 7, ActivityInstanceId = 2, TypeName=System.Activities.Statements.Assign }, State = Closed }
TrackingRecord : ActivityStateRecord { InstanceId = c0c010f2-d75e-4084-a697-16951fde0a57, RecordNumber = 4, EventTime = 2011/05/02 9:59:56, Activity { Name=Delay, ActivityId = 5, ActivityInstanceId = 3, TypeName=System.Activities.Statements.Delay }, State = Executing }
TrackingRecord : WorkflowInstanceRecord { InstanceId = c0c010f2-d75e-4084-a697-16951fde0a57, RecordNumber = 5, EventTime = 2011/05/02 9:59:56, ActivityDefinitionId = Sequence, State = Idle }
TrackingRecord : ActivityStateRecord { InstanceId = c0c010f2-d75e-4084-a697-16951fde0a57, RecordNumber = 6, EventTime = 2011/05/02 9:59:57, Activity { Name=Delay, ActivityId = 5, ActivityInstanceId = 3, TypeName=System.Activities.Statements.Delay }, State = Closed }
TrackingRecord : ActivityStateRecord { InstanceId = c0c010f2-d75e-4084-a697-16951fde0a57, RecordNumber = 7, EventTime = 2011/05/02 9:59:57, Activity { Name=メッセージを表示, ActivityId = 2, ActivityInstanceId = 4, TypeName=Workflow4.Command.DisplayActivity }, State = Executing }
TrackingRecord : ActivityStateRecord { InstanceId = c0c010f2-d75e-4084-a697-16951fde0a57, RecordNumber = 8, EventTime = 2011/05/02 9:59:58, Activity { Name=メッセージを表示, ActivityId = 2, ActivityInstanceId = 4, TypeName=Workflow4.Command.DisplayActivity }, State = Closed }
TrackingRecord : ActivityStateRecord { InstanceId = c0c010f2-d75e-4084-a697-16951fde0a57, RecordNumber = 9, EventTime = 2011/05/02 9:59:58, Activity { Name=Sequence, ActivityId = 1, ActivityInstanceId = 1, TypeName=System.Activities.Statements.Sequence }, State = Closed }
TrackingRecord : WorkflowInstanceRecord { InstanceId = c0c010f2-d75e-4084-a697-16951fde0a57, RecordNumber = 10, EventTime = 2011/05/02 9:59:58, ActivityDefinitionId = Sequence, State = Completed }
実際にトラッキングを行った際には、上記のようなレコードが通知されます。この内容は前回の記事で実際に実行した際の内容です。デザイナ上でトラッキング内容に基づいて表示を行うのですが、その前に追跡用のプロファイルを作成する必要があります。これは「何をトラッキングし通知するか」を設定するものです。
1: 'トラッキングプロファイルの生成
2: customTracker = New VisualTrackingParticipant '独自に用意したトラッキング用クラス3: Dim trcProfile As New TrackingProfile With {.Name = "CustomTrackingProfile"}4: 'トラッキングが必要なアクティビティの名前を設定
5: Dim ctQuery As New CustomTrackingQuery With {.Name = "*", .ActivityName = "*"}6: trcProfile.Queries.Add(ctQuery)7: 'トラッキングが必要なステータスを設定
8: Dim wfiQuery As New WorkflowInstanceQuery9: wfiQuery.States.Add(WorkflowInstanceStates.Started)10: wfiQuery.States.Add(WorkflowInstanceStates.Aborted)11: wfiQuery.States.Add(WorkflowInstanceStates.Canceled)12: wfiQuery.States.Add(WorkflowInstanceStates.Completed)13: wfiQuery.States.Add(WorkflowInstanceStates.Idle)14: wfiQuery.States.Add(WorkflowInstanceStates.Persisted)15: wfiQuery.States.Add(WorkflowInstanceStates.Resumed)16: wfiQuery.States.Add(WorkflowInstanceStates.Suspended)17: wfiQuery.States.Add(WorkflowInstanceStates.Terminated)18: wfiQuery.States.Add(WorkflowInstanceStates.UnhandledException)19: wfiQuery.States.Add(WorkflowInstanceStates.Unloaded)20: wfiQuery.States.Add(WorkflowInstanceStates.Unsuspended)21: trcProfile.Queries.Add(wfiQuery)22: 'ステータスのトラッキングが必要なアクティビティの名前を設定
23: Dim asQuery As New ActivityStateQuery With {.ActivityName = "*"}24: asQuery.States.Add("*")
25: asQuery.Variables.Add("*")
26: trcProfile.Queries.Add(asQuery)27:28: customTracker.TrackingProfile = trcProfile29: _wfApps.Extensions.Add(customTracker)
トラッキングプロファイルを設定するのはこのようなロジックとなります。作成したプロファイルを、WorkflowApplication の Extensions として追加していますが、これは WorkflowInvoker も同様です。
1: Imports System.Activities
2: Imports System.Activities.Tracking
3: Imports System.Collections.Generic
4:5: Public Class VisualTrackingParticipant6: Inherits Tracking.TrackingParticipant
7:8: Public Event TrackingRecordReceived As EventHandler(Of TrackingEventArgs)9:10: Public Property ActivityIdToWorkflowElementMap As Dictionary(Of Integer, activity)11: Public Property ActivityElementMap As Dictionary(Of Object, Debugger.SourceLocation)12:13: Protected Overrides Sub Track(ByVal record As System.Activities.Tracking.TrackingRecord, ByVal timeout As System.TimeSpan)14: OnTrackingRecordReceived(record, timeout)15: End Sub16:17: Protected Sub OnTrackingRecordReceived(ByVal record As TrackingRecord, ByVal timeout As TimeSpan)18:19: Dim resultArgs As New TrackingEventArgs With {.Record = record, .Timeout = timeout}20: Select Case True21: Case TypeOf record Is WorkflowInstanceRecord '10022: Case TypeOf record Is WorkflowInstanceUnhandledExceptionRecord '10123: Case TypeOf record Is WorkflowInstanceAbortedRecord '10224:25: Case TypeOf record Is ActivityStateRecord '10326: If ActivityIdToWorkflowElementMap.ContainsKey(DirectCast(record, ActivityStateRecord).Activity.Id) Then27: resultArgs.Activity = ActivityIdToWorkflowElementMap.Item(DirectCast(record, ActivityStateRecord).Activity.Id)
28: End If29: Case TypeOf record Is ActivityScheduledRecord '10430: If ActivityIdToWorkflowElementMap.ContainsKey(DirectCast(record, ActivityScheduledRecord).Activity.Id) Then31: resultArgs.Activity = ActivityIdToWorkflowElementMap.Item(DirectCast(record, ActivityScheduledRecord).Activity.Id)
32: End If33: Case TypeOf record Is FaultPropagationRecord '10534: Case TypeOf record Is CancelRequestedRecord '10635: Case TypeOf record Is BookmarkResumptionRecord '10736: Case TypeOf record Is CustomTrackingRecord '108,110,11137:38: Case TypeOf record Is WorkflowInstanceSuspendedRecord '11239: Case TypeOf record Is WorkflowInstanceTerminatedRecord '11340:41: End Select42: RaiseEvent TrackingRecordReceived(Me, resultArgs)43:44: End Sub45: End Class46:
独自に用意したトラッキング用クラスはこのようなロジックで行っています。内容としては対象アクティビティが関連する ActivityStateRecord や ActivityScheduledRecord が通知された際に、TrackingRecord の内容から対象アクティビティを確定させてイベントに通知させることを行っています。イベント受け取り側ではこの内容を元に、WorkflowDesigner.DevugManagerView.CurrentLocation にその時点でのアクティビティを設定する事で、デザイナ上に黄色い枠線で囲まれて表示が行われるようになります。
0 件のコメント:
コメントを投稿