0

我有一个使用 WorkflowServiceHost、WorkflowServiceHostFactory 和 WorkflowHostingEndpoint 在 IIS 中托管 WF4.5 工作流的应用程序。

工作流由 VS 2013 在 .xaml 文件中定义。在工作流中,有一个自定义活动用于接收来自用户的输入数据。使用 CreateBookmark 和 Resume 的回调来获取它。

我的问题是:第一个活动执行,工作流实例进入空闲、持久和卸载。在恢复第一个书签后,第二个活动执行,工作流实例只进入空闲状态。因此只有第一个活动使工作流实例持久化和卸载。

为了验证我的主机实现是否有效,我使用了延迟活动并且一切正常。

我的自定义活动:

public sealed class WaitForResponse<TResult> : NativeActivity<TResult>
{
    public string ResponseName { get; set; }

    protected override bool CanInduceIdle
    {
        get
        {
            return true;
        }
    }

    protected override void Execute(NativeActivityContext context)
    {
        context.CreateBookmark(this.ResponseName, new BookmarkCallback(this.ReceivedResponse));            
    }

    protected void ReceivedResponse(NativeActivityContext context, Bookmark bookmark, object obj)
    {
        this.Result.Set(context, (TResult)obj);
    }
}

IWorkflowCreation client = new ChannelFactory<IWorkflowCreation>(new NetNamedPipeBinding(NetNamedPipeSecurityMode.None), new EndpointAddress("net.pipe://localhost/workflowCreationEndpoint")).CreateChannel();

//create an instance
Guid id = client.Create(null);

// Resume        
client.ResumeBookmark(id, "1", "Message 1");

在书签活动(创建书签/恢复)结束后,实例不再持久/卸载。

换句话说,只有第一个加书签的活动集实例才会卸载。是的,我设置了 TimeToPersist/TimeToUnload。

下面是实例的跟踪状态: Started, Idle, Persisted, Unloaded , Resumed, Idle, Idle, Idle, Idle, Idle, Completed, Deleted

我创建了一个示例解决方案来演示该问题。示例供下载。

如果有人可以帮助我,我真的很感激。感谢您的任何帮助!

感谢您的任何帮助!

4

1 回答 1

0

只有当工作流实例进入可持久状态时,工作流实例才会在运行时持久存在,无论是在它空闲还是使用Persist活动时。

WorkflowServiceHost不会让您对工作流实例何时持久化有太多控制,但您可以配置when。检查如何:使用 WorkflowServiceHost 配置空闲行为

报价:

当工作流遇到必须由某些外部刺激恢复的书签时,工作流将进入空闲状态,例如,当工作流实例正在等待使用接收活动传递消息时。WorkflowIdleBehavior 是一种行为,允许您指定服务实例空闲与实例保持或卸载之间的时间。它包含两个属性,使您能够设置这些时间跨度。TimeToPersist 指定工作流服务实例空闲和工作流服务实例持久化之间的时间跨度。TimeToUnload 指定工作流服务实例空闲和卸载工作流服务实例之间的时间跨度,其中卸载意味着将实例持久保存到实例存储并从内存中删除

<behaviors>
    <serviceBehaviors>
        <behavior name="">
            <workflowIdle timeToUnload="0:05:0" timeToPersist="0:04:0"/> 
        </behavior>
    </serviceBehaviors>
</behaviors>

请注意,timeToPersist 的默认值为 MaxValue。因此,尽管您的自定义活动因为您正在创建书签而处于空闲状态,但它永远不会持续存在(至少持续很长时间!!时间)。

编辑:

在使用您的示例并阅读一些文档之后,您需要做的是在OnResolveBookmark中调用SendResponse

protected override 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];

        // !!! Call it here, for example. !!!
        responseContext.SendResponse(null, null);
    }
    else
    {
        throw new NotImplementedException(operationContext.IncomingMessageHeaders.Action);
    }

    return bookmark;
}

这里简要指出:

覆盖 OnResolveBookmark 以手动从传入消息中提取书签。如果重写此方法,则必须在其主体中调用 SendResponse 以响应发送到 WorkflowHostingEndpoint 的消息

我不知道这是否可以被视为一个错误。工作流引擎似乎进入了一种状态,尽管它因为您给它一个书签而变得空闲,但它并不真正知道它,因为从未发送过关于它的响应警告。

于 2014-10-02T16:11:49.243 回答