Want to run more than 1 Windows Worklow Foundation runtime engine in a process?

If you try to create multiple WorkflowRuntime objects in the same process you'll notice that the first engine instance starts up just fine but the subsequent instances all throw exceptions. Windows Workflow Foundation only allows 1 runtime object per AppDomain in a process. This means that if you were thinking you could create a multithreaded application using System.Thread to spawn off new runtime engines for your application logic, in a nutshell, you can't. So what can you do?

The keywords here are "per AppDomain". When I write documentation, I obviously read a lot of developer spec's. One day when I ran across this particular subject so, being the inquisitive guy I am, I tried to create multiple instances and sure enough, the dev didn't lie. Knowing that this question may be raised in the future (actually the question did come up internally), I decided to write a quick sample on how to create multiple runtime instances within the same process.

You can grab the code right here.

When you take a look, you won't see any rocket science here. A class named WorkflowIsolatedHost does the acutal loading of the workflow runtime engine much like you would see in a normal workflow host (e.g. when you create a new console workflow project).

 public class WorkflowIsolatedHost
{
    private WorkflowRuntime workflowRuntime;

    public WorkflowIsolatedHost()
    {
        Console.WriteLine("Created workflow instance in AppDomain: " + AppDomain.CurrentDomain.FriendlyName);

        // Fire up the engine.
        workflowRuntime = new WorkflowRuntime();
        workflowRuntime.StartRuntime();

        // Load our schedule type.
        Type type = typeof(MultipleAppDomainWorkflowTest.Workflow1);

        workflowRuntime.WorkflowCompleted += OnWorkflowCompletion;
        workflowRuntime.StartWorkflow(type);
    }

    void OnWorkflowCompletion(object sender, WorkflowCompletedEventArgs instance)
    {
        Console.WriteLine("Workflow instance finished in AppDomain: " + AppDomain.CurrentDomain.FriendlyName);

        workflowRuntime.StopRuntime();
    }
}

The WorkflowCreator class (below) is the class responsible for creating new AppDomain's and kicking off WorkflowIsolatedHost objects in each of those AppDomain's. Again, not rocket science but it demonstrates the concept pretty well.

 public static class WorkflowCreator
{
    public static void CreateIsolatedWorkflowInstances(int numInstances, string assemblyName, string workflowHostName)
    {
        for (int i = 0; i < numInstances; i++)
        {
            AppDomain curDomain = AppDomain.CreateDomain("WorkflowInstance" + i.ToString());
            curDomain.CreateInstance(assemblyName, workflowHostName);
        }
    }
}

So, now that we've defined 2 helper classes for our application, we can create the main application entry point. All that is needed is to call the WorkflowCreator.CreateIsolatedWorkflowInstances method passing an integer denoting the number of AppDomain (and subsequent workflow runtime engines to start), the assembly name and the class name within that assembly to instantiate in the AppDomain by calling the AppDomain.CreateInstance method.

 class Program
{
    static void Main(string[] args)
    {
        WorkflowCreator.CreateIsolatedWorkflowInstances(5,
            System.Reflection.Assembly.GetExecutingAssembly().FullName,
            typeof(WorkflowIsolatedHost).ToString());
    }
}

There you have it. If you have any questions don't hesitate to send them my way.