Related Articles:
Tracing Service in WF (1): SQL tracking database tables, views, stored procedures, and other related descriptions
Track service in WF (2): Use sqltrackingservice
Track service in WF (3): Use sqltrackingservice to track rules
Tracking Service in WF (4): Use the tracking configuration file
Tracking Service in WF (5): Data Maintenance of sqltrackingservice
In the previous articles, we talked about sqltrackingservice, the WF built-in tracking service. Sometimes we have special requirements. For example, I don't want to store the tracking data in the SQL database. For example, I want to send the tracking information to the specified email. At this time, we can implement our own tracking service. In this article, I will use the least code to implement a file tracking service and store the tracking information in the file.
To develop a custom tracking service, we need to implement two categories: trackingchannel and trackingservice. The tracing channel receives the tracing records sent during running. The runtime tracing infrastructure uses this tracing channel to send trace records associated with workflow instances back to the Host application. The application can process this trace information in any way you choose. For example, sqltrackingservice writes tracking information to the SQL database. The Tracking Service provides the tracking configuration file for the runtime based on the specific parameters and conditions. It is also responsible for providing tracking channels for receiving data sent during runtime.
I. Tracking channel implementation
First, we implement a filetrackingchannel class. The Code is as follows:
Public class filetrackingchannel: trackingchannel {trackingparameters tpara = NULL; streamwriter = file. createtext ("caryworkflowtracklog.txt ");
String strworkflowtracklog = "";
Public filetrackingchannel (trackingparameters tpara) {This. tpara = tpara;} protected override void send (trackingrecord record) {If (record is finished) {workflow wfrecord = record as workflowtrackingrecord; kflowtracklog = "workflow instance information:" + wfrecord. eventdatetime + "" +
Wfrecord. records; writetofile (strworkflowtracklog);} If (record is activitytrackingrecord) {activitytrackingrecord actrecord = record as records; strworkflowtracklog = "activity information:" + actrecord. eventdatetime + "+"
Actrecord. activitytype. Name; writetofile (strworkflowtracklog );}
If (record is usertrackingrecord) {usertrackingrecord userrecord = record as usertrackingrecord; If (userrecord. userdata is ruleactiontrackingevent) {ruleactiontrackingevent ruleaction = userrecord. userdata as ruleactiontrackingevent; strworkflowtracklog = "user information:" + userrecord. eventdatetime + ""
+ Ruleaction. rulename + ruleaction. conditionresult; writetofile (strworkflowtracklog);} else {strworkflowtracklog = "user information:" + userrecord. eventdatetime + "+
Userrecord. userdata; writetofile (strworkflowtracklog) ;}} protected override void instancecompletedorterminated () {writetofile ("log record completed, ID:" + tpara. instanceid. tostring ();} private void writetofile (string tracklogcontent) {streamwriter. autoflush = true; streamwriter. writeline (tracklogcontent );}
}
The send method is one of the two abstract methods that must be implemented. This method is called by the workflow engine whenever trace data is transmitted to the tracing service. This method transfers the first trackingrecord parameter, which can be any of the three trace record types. The instancecompletedorterminated method is another method that must be implemented. This method is called when the workflow instance is completed or terminated. In this class, we write the tracing information to the specified file.
2. Implement trackingservice
The following code implements the filetrackingservice class:
public class FileTrackingService:TrackingService{ private TrackingProfile defaultProfile; public FileTrackingService(): base() { defaultProfile = GetDefaultProfile(); }
protected override TrackingChannel GetTrackingChannel(TrackingParameters parameters) { return new FileTrackingChannel(parameters); }
protected override TrackingProfile GetProfile(Guid workflowInstanceId) { return defaultProfile; }
protected override TrackingProfile GetProfile(Type workflowType, Version profileVersionId) { return defaultProfile; } protected override bool TryGetProfile(Type workflowType, out TrackingProfile profile) { profile = defaultProfile; return true; } protected override bool TryReloadProfile(Type workflowType, Guid workflowInstanceId,
out TrackingProfile profile) { profile = null; return false; } private TrackingProfile GetDefaultProfile() { TrackingProfile profile = new TrackingProfile(); WorkflowTrackPoint workflowPoint= new WorkflowTrackPoint(); List<TrackingWorkflowEvent> workflowEvents= new List<TrackingWorkflowEvent>(); workflowEvents.AddRange(Enum.GetValues(typeof(TrackingWorkflowEvent)) as IEnumerable<TrackingWorkflowEvent>); WorkflowTrackingLocation workflowLocation= new WorkflowTrackingLocation(workflowEvents); workflowPoint.MatchingLocation = workflowLocation; profile.WorkflowTrackPoints.Add(workflowPoint); ActivityTrackPoint activityPoint= new ActivityTrackPoint(); List<ActivityExecutionStatus> activityStatus= new List<ActivityExecutionStatus>(); activityStatus.AddRange(Enum.GetValues(typeof(ActivityExecutionStatus)) as IEnumerable<ActivityExecutionStatus>); ActivityTrackingLocation activityLocation= new ActivityTrackingLocation( typeof(Activity), true, activityStatus); activityPoint.MatchingLocations.Add(activityLocation); profile.ActivityTrackPoints.Add(activityPoint); UserTrackPoint userPoint = new UserTrackPoint(); UserTrackingLocation userLocation = new UserTrackingLocation( typeof(Object), typeof(Activity)); userLocation.MatchDerivedActivityTypes = true; userLocation.MatchDerivedArgumentTypes = true; userPoint.MatchingLocations.Add(userLocation); profile.UserTrackPoints.Add(userPoint); profile.Version = new Version(1, 0, 0); return profile; }
}
The custom tracking service has two tasks. The first is to provide tracking profiles to the workflow engine. Next, he returns an instance of the tracking pipeline to the workflow engine. We can find a filetrackingservice that does not support custom tracking profiles.
3. Use filetrackingservice
In the host Program, we add the filetrackingservice to workflowruntime, as shown below:
FileTrackingService fts = new FileTrackingService();workflowRuntime.AddService(fts);
Put a codeactivity in the workflow, and its executecode Event code is as follows:
Private void codeactivityappsexecutecode (Object sender, eventargs e) {console. writeline ("codeactivity1 is executed! "); Trackdata (" caryuserdata "," caryuserdatarecord ");}
The workflow execution result is as follows:
Our tracking information has been written into the specified file. Of course, we just did the most basic work.