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:
void codeActivity1_ExecuteCode(object sender, EventArgs e)
IDictionary<string, string> context = RightReceiveActivity.Context;
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
IContextManager contextManager = proxy.InnerChannel.GetProperty<IContextManager>();
Where the _context field points to the context used when creating the workflow and the conversationId is returned from the first GetData() call.