我很难弄清楚如何处理事件,Runnable Instances中的Workflow Foundation 4。
我正在努力解决的问题是,即使无法使用对HasRunnableWorkflowEvent
的相应调用来恢复实例,也会从商店返回WorkflowApplication.LoadRunnableInstance()
类型的事件。
这里是the simple Workflow I'm using供我测试:
我具有内置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] ...