So as an update to my earlier post about WF
and Serialization
I’ve discovered another interesting little serialization issue
that relates to activity execution contexts.

If you aren’t familiar with AECs – here are two links to get you going:

http://msdn.microsoft.com/msdnmag/issues/06/01/WindowsWorkflowFoundation/

http://blogs.msdn.com/advancedworkflow/archive/2006/03/21/557121.aspx

The effect this WF feature has on serialization relates to how they’ve implemented
these spawned execution contexts.  Let’s take a simple custom activity inside
of a WhileActivity:

 

As the While executes – each execution cycle creates a new spawned AEC for activity11.

Let’s assume that the Activity has a private field of a type that isn’t serializable
(I’ll re-use the Point type from my last serialization post):

public class Point
{
public int x;
public int y;
}

So what happens?  Well until I use my custom activity inside of  another
activity that creates a spawned AEC (or like the last post – until I add a WorkflowPersistenceService)
– everything is fine.  But once you put this Activity inside of a WhileActivity
– BAM – Serialization exception.

Why?  To understand try this test – create a custom activity – set a breakpoint
inside of the constructor (or use Debug or Console.WriteLine to write out a message
from the constructor) – notice that your constructor gets called twice (see my earlier
post about WorkflowInstance.GetWorkflowDefintion about the second call) and only twice. 
Even if you have a While that executes a hundred times – your constructor is only
called twice.  This is because on each subsequent spawned ActivityExecutionContext
– the runtime calls Activity.Clone to create a new instance – not “new”.  

Of course this is where the serialization exception happens – because the implemenation
of Activity.Clone uses Activity.Save – which is the same method used by the WorkflowPersistence
infrastructure.   This is the method that uses a BinaryFormatter to serialize
the Activity type (they clone the “extra” instance they keep around as the “definition”). 
So they create a new Activity instance for each AEC by serializing the existing instance
and deserializing into a new instance.  Which is why your constructor doesn’t
get called on each execution of the While loop.

Fixing this problem is the same as fixing the serialization issue with WorkflowPersistence. 
It just goes to show you though – that you can have serialization “issues” (when I
say issue I don’t mean to imply that WF has anything wrong with it – quite the opposite
I find the implemenation of AEC’s and Clone to be really well done) even if you don’t
use WorkflowPersistence.