を作成し、複数のWorkflowServiceHostインスタンスを使用してエンジンをホスティングしています。スケジュールされた間隔で起動する、つまりアクティビティを遅延させてジョブを実行し、キャッシュにデータを読み込む、長時間実行するワークフローを作成しました。これらのワークフローは、IIS 7でホストされるカスタムWCFデータサービスであるメインアプリケーションから開始されます。ワークフローを開始するトリガは、User Login、特定のエンティティのRequestから異なります。ワークフローは、私は次のことを達成しようとしています動的
現在、私は標準のリクエスト契約の一部であるトリガをリッスンWCFワークフローサービスを、作成しました。受信したトリガは、アクティビティ定義でWorkflowApplicationをインスタンス化し、ワークフローを開始します。これは、永続性と再水和が手動で行われなければならないので、これには限界があります。
私たちはWebファーム環境を持っているように、フェイルオーバー時に持続性と再水和をサポートするホストとして動作することができWorkflowServiceHostのサンプル、出くわしました。しかし、私が以下のようなことをしようとすると、さまざまなエラーで失敗します。だから、私が正しい方向に進んでいるかどうかを知りたがっているだけです。またはこれは不可能です。 MSDNのサンプルに基づいてIWorkflowCreation契約の実装コードを見つけてください:
` public Guid StartWorkflowReturnGuid(Dictionary<string,object> parameters)
{
Guid id = Guid.Empty;
try
{
System.ServiceModel.Activities.WorkflowServiceHost host = new System.ServiceModel.Activities.WorkflowServiceHost(this.workflow, new Uri("net.pipe://localhost"));
//string myConnectionString =
// "Data Source=localhost\\SQLEXPRESS;Initial Catalog=DefaultSampleStore;Integrated Security=True;Asynchronous Processing=True";
//SqlWorkflowInstanceStoreBehavior sqlWorkflowInstanceStoreBehavior =
// new SqlWorkflowInstanceStoreBehavior(myConnectionString);
//sqlWorkflowInstanceStoreBehavior.HostLockRenewalPeriod = TimeSpan.FromSeconds(30);
//sqlWorkflowInstanceStoreBehavior.RunnableInstancesDetectionPeriod = TimeSpan.FromSeconds(30);
//host.Description.Behaviors.Add(sqlWorkflowInstanceStoreBehavior);
WorkflowUnhandledExceptionBehavior workflowUnhandledExceptionBehavior =
new WorkflowUnhandledExceptionBehavior();
workflowUnhandledExceptionBehavior.Action = WorkflowUnhandledExceptionAction.Terminate;
//Set the TimeToUnload to 0 to force the WF to be unloaded. To have a durable delay, the WF needs to be unloaded otherwise it will be thread as an in-memory delay.
//WorkflowIdleBehavior workflowIdleBehavior = new WorkflowIdleBehavior()
//{
// TimeToUnload = TimeSpan.FromSeconds(0)
//};
//host.Description.Behaviors.Add(workflowIdleBehavior);
host.WorkflowExtensions.Add(new LoginExtensions());
host.WorkflowExtensions.Add(new MarketDataExtensions());
ResumeBookmarkEndpoint endpoint = new ResumeBookmarkEndpoint(new NetNamedPipeBinding(NetNamedPipeSecurityMode.None), new EndpointAddress(string.Format("net.pipe://localhost/workflowCreationEndpoint/{0}",Guid.NewGuid())));
host.AddServiceEndpoint(endpoint);
host.Open();
IWorkflowCreation client = new ChannelFactory<IWorkflowCreation>(endpoint.Binding, endpoint.Address).CreateChannel();
//create an instance
id = client.Create(parameters);
Helper.LogInfo(string.Format("Workflow instance {0} created", id));
}
catch (Exception exception)
{
Helper.LogError(string.Format("Exception starting BatchWorkflowServiceHost for type {0}", this.workflow.GetType().FullName), exception);
}
return id;
}
public class ResumeBookmarkEndpoint : WorkflowHostingEndpoint
{
public ResumeBookmarkEndpoint(Binding binding, EndpointAddress address)
: base(typeof(IWorkflowCreation), binding, address)
{
}
protected override Guid OnGetInstanceId(object[] inputs, OperationContext operationContext)
{
//Create called
if (operationContext.IncomingMessageHeaders.Action.EndsWith("Create"))
{
return Guid.Empty;
}
//CreateWithInstanceId or ResumeBookmark called. InstanceId is specified by client
else if (operationContext.IncomingMessageHeaders.Action.EndsWith("CreateWithInstanceId")||
operationContext.IncomingMessageHeaders.Action.EndsWith("ResumeBookmark"))
{
return (Guid)inputs[0];
}
else
{
throw new InvalidOperationException("Invalid Action: " + operationContext.IncomingMessageHeaders.Action);
}
}
protected override WorkflowCreationContext OnGetCreationContext(object[] inputs, OperationContext operationContext, Guid instanceId, WorkflowHostingResponseContext responseContext)
{
WorkflowCreationContext creationContext = new WorkflowCreationContext();
if (operationContext.IncomingMessageHeaders.Action.EndsWith("Create"))
{
Dictionary<string, object> arguments = (Dictionary<string, object>)inputs[0];
if (arguments != null && arguments.Count > 0)
{
foreach (KeyValuePair<string, object> pair in arguments)
{
//arguments for the workflow
creationContext.WorkflowArguments.Add(pair.Key, pair.Value);
}
}
//reply to client with the InstanceId
responseContext.SendResponse(instanceId, null);
}
else if (operationContext.IncomingMessageHeaders.Action.EndsWith("CreateWithInstanceId"))
{
Dictionary<string, object> arguments = (Dictionary<string, object>)inputs[0];
if (arguments != null && arguments.Count > 0)
{
foreach (KeyValuePair<string, object> pair in arguments)
{
//arguments for the workflow
creationContext.WorkflowArguments.Add(pair.Key, pair.Value);
}
}
}
else
{
throw new InvalidOperationException("Invalid Action: " + operationContext.IncomingMessageHeaders.Action);
}
return creationContext;
}
protected override System.Activities.Bookmark OnResolveBookmark(object[] inputs, OperationContext operationContext, WorkflowHostingResponseContext responseContext, out object value)
{
Bookmark bookmark = null;
value = null;
if (operationContext.IncomingMessageHeaders.Action.EndsWith("ResumeBookmark"))
{
//bookmark name supplied by client as input to IWorkflowCreation.ResumeBookmark
bookmark = new Bookmark((string)inputs[1]);
//value supplied by client as argument to IWorkflowCreation.ResumeBookmark
value = (string) inputs[2];
}
else
{
throw new NotImplementedException(operationContext.IncomingMessageHeaders.Action);
}
return bookmark;
}
}
//ServiceContract exposed on the endpoint
[ServiceContract(Name = "IWorkflowCreation")]
public interface IWorkflowCreation
{
[OperationContract(Name = "Create")]
Guid Create(IDictionary<string, object> inputs);
[OperationContract(Name = "CreateWithInstanceId", IsOneWay=true)]
void CreateWithInstanceId(Guid instanceId, IDictionary<string, object> inputs);
[OperationContract(Name = "ResumeBookmark", IsOneWay = true)]
void ResumeBookmark(Guid instanceId, string bookmarkName, string message);
}
あなたは正しいです。私は当初AppFabric統合を利用するためにWCF Workflow Serviceを使用する予定でしたが、特定のユーザーイベントに基づいてワークフローまたはカスタムアクティビティ(XAML)を動的にインスタンス化する必要があるため、AppFabricを活用する複数の送信/受信ペアのモデルインフラ。その結果、WorkflowApplicationベースのホスティングモデルを使用しました。これは、ワークフローの自動再水和をサポートしていないことを正しく示していますが、期限切れのタイマーをポーリングするロジックを実装する必要があります。したがって、どのように私はWorkflowServiceHostベースのモデルをそれを達成するために持っているのですか? –
上記のコメントは –
でした。CanCreateInstance = trueのワークフローでIWorkflowCreationとReceiveActivityを実行しようとすると、メッセージ:例外ABC.Precaching.Workflow.Activities.ValidateTokenJobのBatchWorkflowServiceHostが開始されます。 例外メッセージ: 'ValidateTokenJob'エンドポイント。これは、アプリケーションに設定ファイルが見つからなかったか、またはサービス名に一致するサービス要素が構成ファイルに見つからないか、またはサービス要素にエンドポイントが定義されていないことが原因です。それは期限切れのタイマーのポーリングを開始するためにWorkflowApplicationについてコメントで –