<CharlieDigital/> Programming, Politics, and uhh…pineapples


Correlation Across Workflow Instances

One of the problems that I've been working on solving recently centered around correlation in workflows.  In simple terms, where a workflow may produce parallel execution paths, correlation allows the runtime to route events to the right workflow execution path.

In every example that I came across on MSDN and online, the sample cases all assumed intra-workflow correlation as opposed to inter-workflow correlation involving "parent-child" workflow instances.

I posted the initial query - and the solution I used - on this subject over at the MSDN forums:

The trick, as it turns out, is that the CorrelationToken must be initialized in the parent workflow.  To accomplish this in the sample, I made a frivolous call to an InitializeCorrelation method on my service interface using a CallExternalMethodActivity, which was marked with the CorrelationInitializer attribute.  This activity executes right before the InvokeWorkflowActivity.

public class WorkflowCommunicationServiceArgs : ExternalDataEventArgs {
private string key;

public string Key {
get { return key; }
set { key = value; }

public WorkflowCommunicationServiceArgs(Guid instanceId, string key)
base(instanceId) {
this.key = key;

public interface IWorkflowCommunicationService {
[CorrelationAlias("key", "e.Key")]
event EventHandler<WorkflowCommunicationServiceArgs> ChildCompleted;

void InitializeCorrelation(string key);

void OnChildCompleted(string key);

public class WorkflowCommunicationService : IWorkflowCommunicationService {
#region IWorkflowCommunicationService Members

public event EventHandler<WorkflowCommunicationServiceArgs> ChildCompleted;

public void InitializeCorrelation(string key) {
Console.Out.WriteLine("Key -> [{0}]", key);

public void OnChildCompleted(string key) {
MessageBox.Show(string.Format("Completed child; Key = [{0}]", key));


public void RaiseChildCompletedEvent(string key) {
if (ChildCompleted != null) {
new WorkflowCommunicationServiceArgs(



In essence, the idea is to have two correlation initializers: one utilized by the parent/outer workflow and one utilized by the child/inner workflow when signaling back to the parent.  It seems kind of counterintuitive to require two initializations...I'm still not sure how this is working under the covers, but it works đŸ™‚

The working example can be downloaded from: http://www.charliedigital.com/junk/CorrelationTest.Working.zip

Posted by Charles Chen

Filed under: .Net, WF Comments Off
Comments (0) Trackbacks (0)

Sorry, the comment form is closed at this time.

Trackbacks are disabled.