Note: This blog post is written using the .NET framework 4.0 Beta 2

Windows Workflow Foundation 4 introduces the concept of bookmarks to temporarily pause activities. A bookmark is basically a named pause point in an activity. The result is that the workflow runtime doesn’t consider an activity to be finished until all its bookmarks are either resumed or removed.

 

That last statement isn’t completely true though as it is only the case when the optional BookmarkOptions aren’t specified or specified as None. With BookmarkOptions.MultipleResume a bookmark can be resumed multiple times, de default is just once, so just resuming a bookmark isn’t enough it actually needs to be removed. The other option is BookmarkOptions.NonBlocking which means that the activity is finished even if the bookmark was never resumed. This last option is useful when you want to be able to receive messages while child activities are executing but you don’t need to receive the message per se. The BookmarkOptions enum is a flag so you can combine both NonBlocking  and MultipleResume if you so desire.

One annoying thing with using bookmarks is that you need to use a NativeActivity and you have to override the CanInduceIdle property and return True as the default of False doesn’t permit bookmarks to be created, even when the NonBlocking option is used.

public class MyBookmarkedActivity : NativeActivity
{
    protected override bool CanInduceIdle
    {
        get { return true; }
    }
 
    protected override void Execute(NativeActivityContext context)
    {
        var bookmark = context.CreateBookmark("MyBookmark", BookmarkResumed);
 
    }
 
    private void BookmarkResumed(NativeActivityContext context, Bookmark bookmark, object value)
    {
        Console.WriteLine("Bookmark resumed with '{0}'.", value);
    }
}

 

Running the workflow and resuming a bookmark is easy when using a WorkflowApplication as seen below.

var wa = new WorkflowApplication(new MyBookmarkedActivity());
 
wa.Run();
 
var data = Console.ReadLine();
wa.ResumeBookmark("MyBookmark", data);
 
Console.ReadLine();

 

Nice and easy right?

Well yes except we also have WorkflowInvoker and WorkflowServiceHost to host our activity and neither contains a ResumeBookmark function. More about that later.

 

Enjoy!

www.TheProblemSolver.nl

Wiki.WindowsWorkflowFoundation.eu