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?
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:
- The scheduler always use the thread of the host to schedule the workitem.
- 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.
- 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?