Freigeben über


The Workflow Parallel Activity and Task Parallelism

Task parallelism (also known as function parallelism and control parallelism) is a form of parallelization of computer code across multiple processors in parallel computing environments. Task parallelism focuses on distributing execution processes (threads) across different parallel computing nodes. It contrasts to data parallelism as another form of parallelism.” – Wikipedia – Task Parallelism

This post is a part of a series on WF, Parallelism and Threading

  1. Windows Workflow Foundation (WF4) Activities and Threads
  2. The Workflow Parallel Activity and Task Parallelism
  3. Windows Workflow (WF4) Task Parallelism with Sequences
  4. Windows Workflow Foundation (WF4) ParallelFor Activity
  5. Windows Workflow Foundation (WF4) - Parallel and ParallelFor Behavior (sample)

Can you achieve Task Parallelism with Windows Workflow Foundation?

Yes… yes you can.  I know, in my previous post (Windows Workflow Foundation (WF4) Activities and Threads) I said that every workflow instance is single threaded.  Within each workflow there is one and only one thread servicing activities.  There are no activities for creating threads or waiting on threads etc.  However, Windows Workflow Foundation (WF4) is well suited to Task Parallelism because

  • Each workflow invoked with WorkflowApplication or a Workflow Service or can be though of as a Task which will run on a different thread
  • Multiple Asynchronous Activities can be invoked at the same time
  • Asynchronous Activities can queue work to another thread using a Task

Parallel with Synchronous Activities

Each workflow you create is a task which is made up of  activities.  As the workflow moves through the activities it will process each one in the order that the activities are scheduled by the parent activity.  Some activities allow you to schedule multiple child activities at a time - Parallel, ParalleFor, Pick and State are all examples of this. Here you see that the Parallel activity has scheduled three child activities which are pushed onto a “Stack” of activities (actually it is a strange hybrid of Queue / Stack we call a Quack).

image

Note: The activities are scheduled in reverse order starting with the last activity (on the right)

If the child activities are synchronous (like CodeActivity<T>) then the process is very simple.  The Workflow Runtime grabs the first activity on the stack and the calls the Activity.Execute() method.  Each activity then begins in the Executing state and as it completes moves to the Closed state.  In the following diagram the Parallel has already invoked and closed activity 1 (which is now removed from the stack) and is now executing activity 2.  Activity 3 is already scheduled and is waiting it’s turn to rise to the top of the stack.

image

If your Parallel activity contains only synchronous activities then it is no different than a Sequence composed of the same activities.

image

The tracking data would show that Activity 1 started and completed, followed by activity 2 and activity 3 in exactly the same way.

Parallel with Asynchronous Activities

To truly realize Task Parallelism with the Parallel activity you must create an activity which is asynchronous (such as an AsyncCodeActivity<T> or contains at least one child activity that is asynchronous such as a Send or Delay activity).  In the following diagram you see a Parallel where the child activity is configured to schedule a Delay activity with a duration of 1 millisecond.  The Delay activity creates a bookmark and returns from the Activity.Execute method.  When an activity returns from the Execute() method with an outstanding bookmark it remains in the Executing state.  Then the Workflow Runtime then pops the next activity off of the scheduled stack and starts executing that one.

In the following diagram, the Parallel has already started executing child activities 1 and 2 which have both created bookmarks so they are still executing.  Activity 3 is on top of the stack so it will be the next activity to execute.

SNAGHTMLcd95bd

After all three child activities have started executing and set bookmarks if the scheduled stack is empty the workflow cannot continue to do work because there are no scheduled child activities so it becomes idle.  Depending upon the settings of the host environment the workflow may now be persisted and possibly even unloaded.

image

In my simple example, I have used a Delay activity to simulate long running work, but you can imagine that the work could be any kind of long running process or I/O operation such as invoking a web service, updating a database or reading/writing a file.  Because these operations take a long time to complete placing asynchronous activities into a parallel allows them to all execute concurrently which provides us with Task Parallelism.

At some later point when the I/O completes or the Delay duration is met the asynchronous activities will resume.  When the activities do complete their work it can be in any order.  In this example, activity 2 has already resumed and completed, activity 1 is resuming and activity 3 is still pending.

image

Summary

Windows Workflow Foundation is very capable of Task Parallelism and is well suited to doing complex work which requires a great deal of coordination.  The Parallel Activity makes it easy to do several asynchronous tasks concurrently and to wait until all (or some) of them complete before continuing to the next activity.

In my next post on Task Parallelism we will consider how the Parallel Activity behaves when used with the Sequence activity.

Happy Coding!

Ron Jacobs
https://blogs.msdn.com/rjacobs
Twitter: @ronljacobs https://twitter.com/ronljacobs

Comments

  • Anonymous
    June 28, 2011
    Ron, Great stuff. Not enough people understand the differences. You should really write a post that shows off how easy it is to implement AsyncCodeActivity<T> by using a TPL Task to act as the IAsyncResult. Then maybe show a more complex scenario with continuations and async I/O that uses TaskCompletionSource<T>. Later, Drew

  • Anonymous
    June 28, 2011
    I did show how to implement an AsyncCodeActivity using a Task in my previous post "Windows Workflow Foundation (WF4) Activities and Threads" blogs.msdn.com/.../windows-workflow-foundation-wf4-activities-and-threads.aspx