Continuations are the base for several useful idioms in programming like coroutines, cooperative multithreading and so on.
In the vanilla .NET framework C# supports a way to emulate them using the yield keyword that was originally intended for custom enumerations, but was soon found out to be much more powerful. Using yield one can define methods that can be interrupted at well defined points and continued when desired, with only minor syntax inconveniences.
Please note that Mono ( 2.6 or above ) include an even better Continuations implementation that works in conjunction wit the CLR itself, but of course this only works on Mono, and not on the vanilla .NET framework. In an project I am doing in my spare time I needed continuations that can also be migrated to different machines ( similar to what the SecondLife servers do ) in order to provide enhanced scalability and load balancing, and it needed to run on the normal Microsoft CLR implementation.
The yield statement in C# generates an implicit state machine in a custom IEnumerator implementation, that executes the parts of your code based on the current state.
These enumerators contain a number of state member fields: xxxstate is an integer that stores the state of the method, xxxcurrent stores the current value the enumerator returns and xxx_this contains the instance on which the method itself was called. Additional members contain hoisted out variables of the method code itself ( e.g the control variables for loops and such ) xxx is a compiled generated prefix that seems to be generated by the order in which the compiler generates the members.
When a method that uses yield is called directly an instance of the compiler generated enumerator is created, the instance that was used for the call is stored in it and it is returned to the caller. The actual method code is only executed when MoveNext is called on the enumerator. This means that a call to the method itself has no side effects and can be done an arbitrary number of times without doing any harm ( except some memory allocations of course ).
So in order to migrate the execution state of such a method we need to execute any number of steps from it, ( using MoveNext of the enumerator returned ), persist the state of the enumerator, load it again on some other machine, call the method again, apply the saved state to the enumerator, and call MoveNext again to continue execution. To achieve this I created a surrogate class for an enumerator that extracts and state members out of an instance and that is serializable, and that allows to apply that state again to a different enumerator of the same type.
I do not serialize the xxxthis member since it gets assigned on the initial method call anyway, and the xxxcurrent member is also not needed since the current value is only interesting to me after a call to MoveNext ( in my case I always return an implementation of my IWaitCondition interface ) Note that this all works only with the style that the C# compiler implements yield based enumerators, and will probably break in VB or other .NET languages. It is also required that any control variables that get hoisted out of the method code are serializable as well but in most situations that is the case anyway, and otherwise can be worked around easily. In order to avoid the reflection overhead I create state member accessors using DynamicMethod that get used on any subsequent usage.