Sunday, February 25, 2007 12:26 AM bart

Workflow - Talking about Local Communication Services synchronization

A question of one of my blog readers: what about multiple workflows calling into the same Local Communication Service concerning possible threading and synchronization issues.

Consider the following scenario. Assume you have one WorkflowRuntime in your host application, together with one registered Local Communication Service defined by the following interface contract:

[ExternalDataExchange] interface IBar { void Bar(int i); void Foo(int i); }

Assume Workflow1 relies on the Bar method while Workflow2 relies on the Foo method, with both workflow definitions like the following:

The whileActivity1 has a condition that evaluatues true at all times (read: endless loop). The sequenceActivity1 acts as the container for a set of activities in the body of the loop, and wraps the callExternalMethodActivity1 (that calls the Bar and Foo method for Workflow1 and Workflow2 respectively) as well as the delayActivity1 (that has a 1 second and a 3 second delay for Workflow1 and Workflow2 respectively).

Next, assume the following host application code (note: there's a little issue in the code below since I'm running more than one workflow and the waitHandle would be set upon completion of one of both, causing the app to terminate - since both workflows won't ever terminate due to the endless loop, this doesn't cause further problems in this particular demo):

1 class Program 2 { 3 static void Main(string[] args) 4 { 5 using(WorkflowRuntime workflowRuntime = new WorkflowRuntime()) 6 { 7 AutoResetEvent waitHandle = new AutoResetEvent(false); 8 workflowRuntime.WorkflowCompleted += delegate(object sender, WorkflowCompletedEventArgs e) {waitHandle.Set();}; 9 workflowRuntime.WorkflowTerminated += delegate(object sender, WorkflowTerminatedEventArgs e) 10 { 11 Console.WriteLine(e.Exception.Message); 12 waitHandle.Set(); 13 }; 14 15 ExternalDataExchangeService edx = new ExternalDataExchangeService(); 16 workflowRuntime.AddService(edx); 17 edx.AddService(new MyService()); 18 19 WorkflowInstance instance1 = workflowRuntime.CreateWorkflow(typeof(TestConcurrency.Workflow1)); 20 instance1.Start(); 21 22 WorkflowInstance instance2 = workflowRuntime.CreateWorkflow(typeof(TestConcurrency.Workflow2)); 23 instance2.Start(); 24 25 waitHandle.WaitOne(); 26 } 27 } 28 }

where MyService implements the IBar interface:

class MyService : IBar { public void Bar(int n) { for (int i = 0; i < 100; i++) { Thread.Sleep(10); Console.Write('#'); } } public void Foo(int n) { for (int i = 0; i < 100; i++) { Thread.Sleep(10); Console.Write('@'); } } }

Question: Predict the console output of the workflow execution above. Tip: what about adding [MethodImpl(MethodImplOptions.Synchronized)] to the method declarations? What about inspecting the ManagedThreadId property of the Thread.CurrentThread in both methods?

Happy threading!

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

Filed under:

Comments

# Bar Restaurant &raquo; Workflow - Talking about Local Communication Services synchronization

# New and Notable 147

Friday, March 02, 2007 11:57 AM by Sam Gentile

Harry wonders if it has been a slow week. It started that way for me but its certainly not now with both