Worflow Foundation 4持久性和“可运行实例”的概念

时间:2019-03-21 07:44:28

标签: .net workflow-foundation

我很难弄清楚如何处理事件,Runnable Instances中的Workflow Foundation 4

我正在努力解决的问题是,即使无法使用对HasRunnableWorkflowEvent的相应调用来恢复实例,也会从商店返回WorkflowApplication.LoadRunnableInstance()类型的事件。

这里是the simple Workflow I'm using供我测试:

Workflow with Delay Activity, followed by Bookmark Activity

我具有内置SqlWorkflowInstanceStore实现的设置持久性,并在引擎PersistableAction.Unload回调时指示工作流实例到PersistableIdle

  • 首先,有一个Delay活动。我希望工作流变得空闲,然后再卸载。在那个阶段,对可运行实例的检测返回正匹配,我可以使用对WorkflowApplication.LoadRunnableInstance()的相应调用,然后对WorkflowApplication.Run()的调用来恢复执行。

这是代码的概要:

var instanceId = RunWorkflow(store);

var succeeded = WaitForRunnableInstance(store, handle, TimeSpan.FromSeconds(15.0));
if (!succeeded)
{
     Console.Error.WriteLine("Unable to find runnable instances. Aborting.");
     return;
}

ResumeRunnableInstance(store);

...

使用以下辅助方法:

private static Guid RunWorkflow(InstanceStore store)
{
    var app = CreateWorkflow(store);
    app.Run();
    return app.Id;
}

private static void ResumeRunnableInstance(InstanceStore store)
{
    var app = CreateWorkflow(store);
    app.LoadRunnableInstance();
    app.Run();
}

private static WorkflowApplication CreateWorkflow(InstanceStore store)
{
    var activity = new WorkflowApp();
    var app = new WorkflowApplication(activity);
    app.AddInitialInstanceValues(InstanceValues);
    app.InstanceStore = store;

    SetEvents(app);

    return app;
}
  • 然后,有一个自定义活动,该活动注册了书签和CanInduceIdle。在此阶段,工作流变得空闲并被卸载。不幸的是,我的可运行实例检测返回的正匹配项不是我期望的 。因此,我尝试使用上面显示的相同顺序的调用来恢复工作流,只是收到一个InstanceNotReadyException。那时,如果我使用正确的呼叫顺序,WorkflowApplication.Load()然后WorkflowApplication.ResumeBookmark()工作流将正确恢复。

这是对应的代码:

while (true)
{
    Console.WriteLine();
    Console.WriteLine("Please, press ENTER to exit or type a bookmark name and ENTER to resume the specified bookmark.");

    var bookmarkName = Console.ReadLine();

    if (String.IsNullOrEmpty(bookmarkName))
        return;

    var has = WaitForRunnableInstance(store, handle, TimeSpan.FromSeconds(15.0));

    if (has)
    {
        try
        {
            ResumeRunnableInstance(store);
        }
        catch (InstanceNotReadyException)
        {
            // this is a bug
            // there should not be a runnable instance event
            // when the workflow is waiting for resumption on a bookmark

            Console.Error.WriteLine("An attempt to resume a runnable instance has failed.");
            Console.WriteLine($"Resuming workflow with bookmark: \"{bookmarkName}\".");
            ResumeWorkflow(store, instanceId, bookmarkName);
        }
    }
    else
    {
        Console.WriteLine($"Resuming workflow with bookmark: \"{bookmarkName}\".");
        ResumeWorkflow(store, instanceId, bookmarkName);
    }
}

使用以下辅助方法:

private static void ResumeWorkflow(InstanceStore store, Guid instanceId, string bookmarkName)
{
    var app = CreateWorkflow(store);
    app.Load(instanceId);

    System.Diagnostics.Debug.Assert(app.Id == instanceId);

    app.ResumeBookmark(bookmarkName, new object(), TimeSpan.FromSeconds(10.0));
}

我的理解是,可运行实例检测不应返回正匹配。实际上,如果我删除了Delay活动,即使可操作的工作流由于设置了书签而变得空闲,可运行的实例检测也永远不会返回正匹配。

有没有正确的方法来处理这种情况?在catch块中插入代码对我来说真的很[hack] ...

0 个答案:

没有答案