views:

525

answers:

1

I was wonder about the proper usage of ManualWorkflowSchedulerService.RunWorkflow(). Do I need to synchronize calls to the same workflowInstanceId across threads when I call ManualWorkflowSchedulerService.RunWorkflow?

+2  A: 

No, I don't think so. Following is a relevant excerpt from the book 'Essential Windows Workflow Foundation'

Although operations on WorkflowInstance can be invoked on arbitrary threads, the WF scheduler hosted within the program instance is serviced by a single thread. The WF runtime guarantees that no other thread can interfere or service the scheduler while its dispatcher loop is actively processing work items. To be clear, the hosting application can invoke methods of WorkflowInstance on separate threads concurrently - this does not affect the scheduler executing the activities on a dedicated thread (for an episode of execution).


EDIT: In order to further investigate the issue, I created a wf with a ParallelActivity which contains two HandleExternalEvent activities. The invoked handler of each activity simply puts its thread to sleep for 3 seconds. In the host program, I created two threads and trigger the two events via the service. Moreover, I subclass the ManualWorkflowSchedulerService in order to track its Schedule method. Here are the results (the time is in 10ths of ms):

Src    Time Thread
HOST   7616      1 CreateWorkflow
MWSS   7642      1 Schedule workflow
HOST   8297     12 Trigger event 1 and wait for RunWorkflow
MWSS   8316     12 Schedule workflow
  WF   8327     12 Handler 1 Invoked...wait 3 sec
HOST   8327      1 Press any key to exit...
HOST   8767     13 Trigger event 2 and wait for RunWorkflow
MWSS   8784     13 Schedule workflow
  WF  38319     12 Handler 1 Completed
  WF  38406     12 Handler 2 Invoked...wait 3 sec
  WF  68396     12 Handler 2 Completed
HOST  68573     13 RunWorkflow for event 2 completed in 5,98 sec
HOST  68794     12 WorkflowCompleted
HOST  68795     12 RunWorkflow for event 1 completed in 6,05 sec

Some remarks:

  1. The scheduler always use the thread of the host to schedule the workitem.
  2. The workflow instance does not always use the thread of the host to execute the activities. If another activity is already executing in a thread, then this thread is used for executing all scheduled activities.
  3. The execution of the handlers is thread-safe, but both threads wait both handlers to finish!

If the latter is your concern, I would suggest the following posts:

BTW, can you share some info about the scenario that you are facing?

Panos
I think your quotation my be specific to the DefaultWorkflowSchedulerService, as it describes the separate thread behavior as being an aspect of the scheduler. It also says the scheduler hosted by a single thread, which is not true for the ManualWorkflowSchedulerService.
Frank Schwieterman
Maybe you are right about the quotation, but (as Reflector reveals) the ManualWorkflowSchedulerService uses an internal synchronized dictionary to handle (both schedule and execute) all the workitems, so again I think that invoking the same instance from different threads is safe.
Panos
Nice work Panos.The scenario is an ASP.NET app where there is one workflow per user. Potentially the user could be making multiple requests at the same time. It'd be unfortunate for multiple threads to wait on the single workflow instance, but thats a problem in non-asynch ASP.NET not WF.
Frank Schwieterman