This is just a quick post regarding a “gotcha” our development team encountered when creating a Windows Workflow custom tracking record.
What we were trying to do
We created a custom activity which needed to send messages to possibly many other Workflow services (or Extensions). We thought that registering the services as workflow tracking participants would allow for this.
To send a message to the tracking participant we created a custom tracking record object.
using System.Activities.Tracking;
public class MyTrackingRecord : CustomTrackingRecord
{
public MyTrackingRecord()
: base("MyTrackingRecord")
{
}
public string ExtraData { get; set; }
}
And a tracking participant
using System;
using System.Activities.Tracking;
public class MyTrackingParticipant : TrackingParticipant
{
protected override void Track(TrackingRecord record, TimeSpan timeout)
{
var myRecord = record as MyTrackingRecord;
if (myRecord != null)
{
//do something
}
}
}
This does not work
It seems like a simple solution but the record as MyTrackingRecord always returns null. In fact the only type that the record can be sucessfully cast to is a CustomTrackingRecord.
After decompiling the CustomTrackingRecord I noticed that class implements the Clone() method and returns a new record. My guess is that the tracking system clones all the record objects before sending them to each participant. I don’t know that for sure but it seems reasonable that one participant would not be able to change the object in memory and affect the operation of another participant.
The Solution
After adding a Clone() method the problem was resolved.
protected override TrackingRecord Clone()
{
return new MyTrackingRecord { ExtraData = ExtraData };
}
There, now I was able to cast to a MyTrackingRecord type and my code executed properly. In the future I would just use the CustomTrackingRecord object which has a Name property to identify the record type and a key-value dictionary for added data. The reason we chose to go with a typed object was to reduce the use of “magic strings” that define functionality in the solution.
So by no means is this the only custom tracking solution it was just the path we were heading down.
I hope this helps you out of a jam and as always thanks for reading.