我在微软论坛上发布了这个问题,但想在此发布以获得更多曝光。我到处寻找一个我没想运气的例子。
基本上,我想使用WorkflowApplication以及WorkflowIdentity和持久性存储来实现持久延迟。我使用WorkflowApplication是因为我们有数百个需要动态运行的工作流,因此WorkflowServiceHost在我们的场景中并不可行。
我使用Microsoft提供的示例AbsoluteDelay作为起点,它完美无缺。当我尝试将WorkflowIdentity传递给WorkflowApplication的构造函数时出现问题。
然后,InstanceStore上的WaitForEvents事件不会触发,因为它期望默认身份(id 1),而不是我的新身份(id 2)。执行store.Execute的行在IdentityOwnerTable中创建一条记录,SurrogateIdentityId设置为1而不是我的身份的id。
如何告诉InstanceStore使用我的新身份而不是默认身份?似乎它可以在CreateWorkflowOwnerCommand元数据中传递。
// Create the InstanceStore
SqlWorkflowInstanceStore store = new SqlWorkflowInstanceStore(_workflowDB);
// A well known property that is needed by WorkflowApplication and the InstanceStore
private static readonly XName _workflowHostTypePropertyName = XNamespace.Get("urn:schemas-microsoft-com:System.Activities/4.0/properties").GetName("WorkflowHostType");
// Create the XName for the workflow using the workflow's unique name
XName wfHostTypeName = XName.Get(workflowName);
// Configure a Default Owner for the instance store so instances can be re-loaded from WorkflowApplication
private static InstanceHandle CreateInstanceStoreOwner(InstanceStore store, XName wfHostTypeName)
{
InstanceHandle ownerHandle = store.CreateInstanceHandle();
CreateWorkflowOwnerWithIdentityCommand ownerCommand = new CreateWorkflowOwnerWithIdentityCommand()
{ //changed from CreateWorkflowOwnerCommand (did not fix problem)
InstanceOwnerMetadata =
{
{ _workflowHostTypePropertyName, new InstanceValue(wfHostTypeName) },
// Something here to identify the WorkflowIdentity ??
}
};
store.DefaultInstanceOwner = store.Execute(ownerHandle, ownerCommand, TimeSpan.FromSeconds(30)).InstanceOwner;
return ownerHandle;
}
private static void WaitForRunnableInstance(InstanceStore store, InstanceHandle ownerHandle)
{
// Only fires when using default Identity
IEnumerable<InstancePersistenceEvent> events = store.WaitForEvents(ownerHandle, TimeSpan.MaxValue);
bool foundRunnable = false;
// Loop through the persistence events looking for the HasRunnableWorkflow event (in this sample, it corresponds with
// the workflow instance whose timer has expired and is ready to be resumed by the host).
foreach (InstancePersistenceEvent persistenceEvent in events)
{
if (persistenceEvent.Equals(HasRunnableWorkflowEvent.Value))
{
foundRunnable = true;
break;
}
}
if (!foundRunnable)
{
throw new ApplicationException("Unexpected: No runnable instances found in the instance store");
}
}