The Problem Solver

Tell me and I will forget
Show me and I will remember
Involve me and I will understand
- Confucius -

Google Ads

This Blog

Syndication

Search

Tags

News





  • View Maurice De Beijer's profile on LinkedIn

Community

Email Notifications

Explore

Archives

Long running workflows and the ReceiveActivity

Using a ReceiveActivity is a great way of exposing a workflow via a WCF proxy.

Get started by creating a new project based upon "Sequential Workflow Service Library". This is found in the WCF projects node instead of the Worflow projects node!

Create a service interface, mine is nice and simple and add a few ReceiveActivity to the workflow and hoop up the service interface to the activities. No big deal so far and we can test things by just pressing F5 and having the WCF Test Client. Actually you can only call functions that are hooked up to an ReceiveActivity with the CanCreateInstance set to True so the WCF Test Client might not be all that useful here if you use multiple ReceiveActivity that are part of a single workflow or conversation.

Next step is to create a simple console application as a client with the following code:

Sub SimpleDemo()

Dim proxy As New ServiceReference1.DoStuffClient

Console.WriteLine(proxy.AskQuestion("Is this cool?"))

proxy.AllDone()

End Sub

 

This code works just fine Smile until we decide to split it up and recreate the WCF proxy object for part two like this Sad:

Private Sub Part1()

Dim proxy As New ServiceReference1.DoStuffClient

proxy.GetStarted("Maurice")

Console.WriteLine(proxy.AskQuestion("To be or not to be?"))

End Sub

 

Private Sub Part2()

Dim proxy As New ServiceReference1.DoStuffClient

Console.WriteLine(proxy.AskQuestion("Is this cool?"))

proxy.AllDone()

End Sub

 

In this case the second proxy object doesn't work at all and we get a FaultException with the message "There is no context attached to incoming message for the service and the current operation is not marked with "CanCreateInstance = true". In order to communicate with this service check whether the incoming binding supports the context protocol and has a valid context initialized."

So what gives? Well the WCF service needs to know which workflow the request needs to be routed to and uses the WorkflowInstanceId to do so. When you create a proxu and do the first call this WorkflowInstanceId is automatically added and resent with the next request. So we need to retrieve this WorkflowInstanceId and, when we create the second proxy object, add it again. Doing so turns out to be pretty simple and only takes a few extra lines of code:

Private _instanceId As String

 

Private Sub Part1()

Dim proxy As New ServiceReference1.DoStuffClient

proxy.GetStarted("Maurice")

Dim contextManager As IContextManager = _

proxy.InnerChannel.GetProperty(Of IContextManager)()

Dim context As Dictionary(Of String, String) = _

contextManager.GetContext()

_instanceId = context("instanceId")

Console.WriteLine(proxy.AskQuestion("To be or not to be?"))

End Sub

 

Private Sub Part2()

Dim proxy As New ServiceReference1.DoStuffClient

Dim contextManager As IContextManager = _

proxy.InnerChannel.GetProperty(Of IContextManager)()

Dim context As New Dictionary(Of String, String)

context.Add("instanceId", _instanceId)

contextManager.SetContext(context)

Console.WriteLine(proxy.AskQuestion("Is this cool?"))

proxy.AllDone()

End Sub

 

Basically what we need to do is retrieve the workflow instanceId from the context that is returned with the first call and save that. Next time we create a new proxy object we need to store the same instanceId in the request context before we actually use it and we are good to go Smile Setting the instaceId is actually done through a ClientContextProtocol object which is returned as an IContextManager inside of the channel properties. Check the bold lines in the previous code sample.

So why is this so important?

Well one of the most powerful features of Workflow Foundation is its capability to have long running workflows. Now long running workflows would not be very useful if the client application needs to keep its proxy alive for as long as it need to communicate with the workflow. Guess that would make "long running" a very relative thing. But with this technique all the client has to do is save the workflow instanceId somewhere, perhaps a database table, and it can reconnect to the same workflow at a later point in time.

Enjoy!

Published Wed, Feb 6 2008 21:04 by Maurice
Filed under: , , , , ,

Comments

# ReceiveActivity, ContextTokens and conversations@ Monday, March 24, 2008 9:21 AM

In a previous blog post I showed how to use the ReceiveActivity with long running workflow and how to

# ReceiveActivity, ContextTokens and conversations@ Monday, March 24, 2008 9:37 AM

In a previous blog post I showed how to use the ReceiveActivity with long running workflow and how to

# re: Long running workflows and the ReceiveActivity@ Wednesday, April 09, 2008 2:01 PM

I just posted some more info on correlating workflows in relation to WCF hosted workflows: www.develop-one.net/.../CorrelatingWorkflowsUsingWindowsCommunicationFoundation.aspx

# Correlating Workflows using Windows Communication Foundation@ Wednesday, May 21, 2008 7:35 AM

 

# The Blomsma Code - Correlating Workflows using Windows Communication Foundation@ Wednesday, May 21, 2008 7:35 AM

Pingback from  The Blomsma Code - Correlating Workflows using Windows Communication Foundation

# re: Long running workflows and the ReceiveActivity@ Monday, June 09, 2008 6:53 PM

can u please email me the source code for the above...

thanks

mo

mohit.akl at gmail.com

by mohit

# re: Long running workflows and the ReceiveActivity@ Tuesday, December 23, 2008 10:41 AM

Thanks, this was very helpful!