ReceiveActivity, ContextTokens and conversations

In a previous blog post I showed how to use the ReceiveActivity with long running workflow and how to extract the workflow instanceId from the context using the IContextManager. I also showed how to rebuild this context at a later date when you use a new proxy object to call the same workflow instance.

But what happens when there are multiple ReceiveActivity instances waiting for the same request in a workflow. In the workflow below both indicated activities are in a parallel activity so they are waiting at the same time and for the same request.

The way to keep them apart is by specifying the ContextToken for the two ReceiveActivity objects. The picture below shows the ReceiveActivity to the right, the one to the left has a ContextToken named LeftBranch.

Now we know how to keep them apart in the workflow we still need a way to specify this at the clients end. This is done using a conversationId setting on the same context as we specified the instanceId. The only problem here is that this conversationId is a Guid and not something the client can determine by itself so the workflow needs to supply it somehow. For this example I just kept things simple and returned the conversationId from the first ReceiveActivity call. This is the code in the CodeActivity that does just that:

private void codeActivity1_ExecuteCode(object sender, EventArgs e)

{

IDictionary<string, string> context = RightReceiveActivity.Context;

 

string temp;

 

if (context.TryGetValue(“conversationId”, out temp))

ReturnValue = temp;

}

 

All I need to do is het the Context from the ReceiveActivity I am interested in, the right one in this case, and retrieve the conversationId from it. Remember the context is an IDictionary<string, string> and it will also contain the instanceId for the workflow. In fact I could have just returned this context to the client for future use but as I was using the simple standard interface generated and the client already knew the workflow instanceId I decided to skip this step.

The client code to set the conversationId is simple:

Workflow1Client proxy = new Workflow1Client();

 

IContextManager contextManager = proxy.InnerChannel.GetProperty<IContextManager>();

if (!string.IsNullOrEmpty(_conversationId))

_context.Add(“conversationId”, _conversationId);

 

contextManager.SetContext(_context);

 

DumpContext(proxy);

 

Console.WriteLine(proxy.GetData(2));

 

Where the _context field points to the context used when creating the workflow and the conversationId is returned from the first GetData() call.

 

Enjoy!

www.TheProblemSolver.nl
http://wiki.WindowsWorkflowFoundation.eu

One thought on “ReceiveActivity, ContextTokens and conversations

  1. Please could you help me. My issue is that I have a custom activity, each with a Receive Activity. I could se the ContextToken in my custom Activity, but when I place duplicate copies of my activity on my workflow I get an error saying that the workflowinstanceId cannot be found in the database. I realise this is because the second call has some memory of the first and has somehow cached the settings, I assume this has to do with the ContextToken not being unique. Is there a way I can dynamically set the ContextToken? Any help would be greatly appreciated.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>