I stumbled upon this post by Nate Talbert http://blogs.msdn.com/advancedworkflow/archive/2006/02/23/538160.aspx explaining why a workflow instance is single-threaded.  Some of the exact implementation details are a little bit out-of-date now that WF 4.0 is close to release, but the points made are still very valid.

In order to simplify the Activity authoring experience, WF guarantees that all Activities belonging to the same workflow instance will execute in the same thread.  However, a workflow can still easily exhibit multi-threaded behavior:

  • Activities can and do take advantage of .NET’s BeginInvoke() and EndInvoke() pattern to execute a task using a thread from the .NET thread pool.  This usage of existing threads is more efficient than always starting a new thread.  Using file read as an example, the Activity itself should only execute for a very brief amount of time in the workflow thread.  The hard-lifting is done behind the scenes by Windows and .NET to asynchronously read the file and return its contents.  Database and PowerShell Activities are other examples that can take advantage of this pattern.
  • Assuming the task can be called using a .NET method, the InvokeMethod Activity can be used to run it in a separate thread without the need to write a custom Activity, thereby providing the capability to coordinate custom tasks that can block.

A single workflow instance is single-threaded for simplicity and performance reasons, while at the same time, it fully exhibits multi-threaded behavior in an efficient and .NET-compliant way.