1
votes

I'm implementing a stare machine application using WF 4.5; this workflow is hosted by a WCF service using the WorkflowApplication class. It's intended to be used by an ASP.NET MVC application that queries the WCF service for redirecting to specific pages mapped to the states defined in the state machine workflow. I need that the execution of the workflow should be synchronous in order to give to the MVC application the current state when a transition is called; I'm forcing a SynchronousSynchronizationContext as described in this article:

http://www.develop.com/synchworkflow

but I'm facing a strange behavior; when I call the workflow application for the first time everything works fine and the workflowapplication performs its task in a synchronous fashion. However when I call the resume (the workflow is persisted) through a bookmark the workflowapplication executes in an async fashion event though I'm still forcing a synchronous SynchronizationContext.

Below there is an extract of the code I'm using:

public class WorkflowManager
{
    public Guid Run(Activity activity, IDictionary<string, object> parameters)
    {
        WorkflowApplication wfApp = SetUpInstance(activity, parameters);
        wfApp.Run();

        return wfApp.Id;
    }

    public void Resume(Guid id, Activity activity, string bookmarkName)
    {

        WorkflowApplication wfApp = SetUpInstance(activity, null);
        wfApp.Load(id);

        wfApp.ResumeBookmark(bookmarkName, "test");
    }

    WorkflowApplication SetUpInstance(Activity activity, IDictionary<string, object> parameters)
    {
        Guid id = Guid.Empty;

        WorkflowApplication wfApp = null;
        if (parameters != null)
        {
            wfApp = new WorkflowApplication(activity, parameters);
        }
        else
        {
            wfApp = new WorkflowApplication(activity);
        }

        SynchronousSynchronizationContext syncContext = new SynchronousSynchronizationContext();
        wfApp.SynchronizationContext = syncContext;

        wfApp.Idle = AppIdle;
        wfApp.PersistableIdle = (e) =>
        {
            return PersistableIdleAction.Unload;
        };
        wfApp.Aborted = AppAborted;
        wfApp.OnUnhandledException = AppException;

        ChangedStateNotifier extensionNotifier = new ChangedStateNotifier();
        extensionNotifier.Notification += delegate(object sender, HostNotifyEventArgs e)
        {
            if (ChangedState != null)
            {
                ChangedState(e.WorkflowId, e.WorkflowStatus);
            }
        };

        wfApp.InstanceStore = store;
        wfApp.Extensions.Add(extensionNotifier);

        return wfApp;
    }
}

I appreciate everyone could give me an hint at what I'm doing wrong. Thanks and regards.

1

1 Answers

1
votes

Example from http://www.develop.com/synchworkflow is not fully functional. That implementation of sync context handles only invocation until Idle or Abort events which are executed from different threads. Same is for ResumeBookmark. Little bit more complex implementation of sync context is required. There is an example in .net framework (though it is private class that cannot be used). The class is PumpBasedSynchronizationContext in System.Activities.WorkflowApplication, System.Activities.

Similar question to this is: How to execute WorkflowApplication Synchronously