Custom Tracking

The CustomTracking sample demonstrates how to create a custom tracking participant and write the contents of the tracking data to console. In addition, the sample demonstrates how to emit CustomTrackingRecord objects populated with user defined data. The console-based tracking participant filters the TrackingRecord objects emitted by the workflow using a tracking profile object created in code.

Sample Details

Windows Workflow Foundation (WF) provides a tracking infrastructure to track execution of a workflow instance. The tracking runtime implements a workflow instance to emit events related to the workflow lifecycle, events from workflow activities and custom tracking events. The following table details the primary components of the tracking infrastructure.

Component Description
Tracking runtime Provides the infrastructure to emit tracking records.
Tracking participants Consumes the tracking records. .NET Framework 4 ships with a tracking participant that writes tracking records as Event Tracing for Windows (ETW) events.
Tracking profile A filtering mechanism that allows a tracking participant to subscribe for a subset of the tracking records emitted from a workflow instance.

The following table details the tracking records that the workflow runtime emits.

Tracking Record Description
Workflow instance tracking records. Describes the life cycle of the workflow instance. For example, an instance record is emitted when the workflow starts or completes.
Activity state Tracking Records. Details activity execution. These records indicate the state of a workflow activity such as when an activity is scheduled or when the activity completes or when a fault is thrown.
Bookmark resumption record. Emitted whenever a bookmark within a workflow instance is resumed.
Custom Tracking Records. A workflow author can create Custom Tracking Records and emit them within the custom activity.

The tracking participant subscribes for a subset of the emitted TrackingRecord objects using tracking profiles. A tracking profile contains tracking queries that allow subscribing for a particular tracking record type. Tracking profiles can be specified in code or in configuration.

Custom Tracking Participant

The tracking participant API allows extension of the tracking runtime with a user provided tracking participant that can include custom logic to handle TrackingRecord objects emitted by the workflow runtime.

To write a tracking participant the user must implement TrackingParticipant. Specifically, the Track method has to be implemented by the custom participant. This method is called when a TrackingRecord is emitted by the workflow runtime.

public abstract class TrackingParticipant
    protected TrackingParticipant();

    public virtual TrackingProfile TrackingProfile { get; set; }
    public abstract void Track(TrackingRecord record, TimeSpan timeout);

The complete tracking participant is implemented in the ConsoleTrackingParticipant.cs file. The following code example is the Track method for the custom tracking participant.

protected override void Track(TrackingRecord record, TimeSpan timeout)
    WorkflowInstanceRecord workflowInstanceRecord = record as WorkflowInstanceRecord;
    if (workflowInstanceRecord != null)
            " Workflow InstanceID: {0} Workflow instance state: {1}",
            record.InstanceId, workflowInstanceRecord.State));

    ActivityStateRecord activityStateRecord = record as ActivityStateRecord;
    if (activityStateRecord != null)
        IDictionary<String, object> variables = activityStateRecord.Variables;
        StringBuilder vars = new StringBuilder();

        if (variables.Count > 0)
            foreach (KeyValuePair<string, object> variable in variables)
                    "\t\tName: {0} Value: {1}", variable.Key, variable.Value));
            " :Activity DisplayName: {0} :ActivityInstanceState: {1} {2}",
                activityStateRecord.Activity.Name, activityStateRecord.State,
            ((variables.Count > 0) ? vars.ToString() : String.Empty)));

    CustomTrackingRecord customTrackingRecord = record as CustomTrackingRecord;

    if ((customTrackingRecord != null) && (customTrackingRecord.Data.Count > 0))


The following code example adds the console participant to the workflow invoker.

ConsoleTrackingParticipant customTrackingParticipant = new ConsoleTrackingParticipant()
    // The tracking profile is set here, refer to Program.CS

WorkflowInvoker invoker = new WorkflowInvoker(BuildSampleWorkflow());

Emitting Custom Tracking Records

This sample also demonstrates the ability to emit CustomTrackingRecord objects from a custom workflow activity:

The following example demonstrates how to emit CustomTrackingRecord objects within a custom activity.

// Create the Custom Tracking Record
CustomTrackingRecord customRecord = new CustomTrackingRecord("OrderIn")
    Data =
        {"OrderId", 200},
        {"OrderDate", "20 Aug 2001"}

// Emit custom tracking record

To use this sample

  1. Using Visual Studio, open the CustomTrackingSample.sln solution file.

  2. To build the solution, press CTRL+SHIFT+B.

  3. To run the solution, press CTRL+F5.

See also