【问题标题】:WF 4.5 Bookmarked custom activity not fire persist/unloadWF 4.5 书签自定义活动不会触发持久/卸载
【发布时间】:2014-10-02 14:49:43
【问题描述】:

我有一个使用 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。

这是实例的跟踪状态: 已开始、空闲、持续、已卸载、恢复、空闲、空闲、空闲、空闲、空闲、已完成、已删除

我创建了一个示例解决方案来演示该问题。 Sample for download.

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

感谢您的帮助!

【问题讨论】:

    标签: .net workflow-foundation-4 workflow-foundation-4.5


    【解决方案1】:

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

    WorkflowServiceHost 无法让您对工作流实例何时持久化提供太多控制,但您可以配置 when。检查How to: Configure Idle Behavior with WorkflowServiceHost

    引用:

    工作流在遇到必须恢复的书签时会闲置 通过一些外部刺激,例如当工作流实例 等待使用 Receive 活动传递消息。 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;
    }
    

    这里简要指出here

    覆盖 OnResolveBookmark 以手动从 传入消息。如果重写此方法,则必须调用 SendResponse 在其正文中以便响应发送到的消息 工作流托管端点

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

    【讨论】:

    • 在我的 WorkflowServiceHostFactory 类中,我通过 WorkflowIdleBehavior 配置了 workflowIdle。这适用于第一个活动,但第二个实例仅保持空闲状态。
    • 请查看我发布的示例。
    • 它奏效了,真是一种解脱。我要感谢您的帮助,您非常有帮助。我欠你的债@jota。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-03
    • 1970-01-01
    • 2012-07-22
    • 2020-01-17
    相关资源
    最近更新 更多