この質問を Microsoft フォーラムに投稿しましたが、ここに投稿してさらに公開したいと思いました。私は運が悪いと私がやろうとしていることの例をどこでも探しました。
基本的に、永続的な遅延を実現するために、WorkflowApplication を WorkflowIdentity および永続ストアと共に使用したいと考えています。私が WorkflowApplication を使用するのは、動的に実行する必要がある数百のワークフローがあるためです。このシナリオでは、WorkflowServiceHost は現実的ではありません。
Microsoft が提供する例の AbsoluteDelay を出発点として使用しましたが、完全に機能します。WorkflowIdentity を WorkflowApplication のコンストラクターに渡そうとすると、問題が発生します。
次に、InstanceStore の WaitForEvents イベントは発生しません。これは、新しい ID (ID 2) ではなく、デフォルトの ID (ID 1) を想定しているためです。store.Execute を実行する行は、私の ID の代わりに SurrogateIdentityId を 1 に設定して、IdentityOwnerTable にレコードを作成します。
デフォルトの ID ではなく、新しい 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");
}
}