破碎的WF4工作流程补液

时间:2013-08-27 12:52:51

标签: wcf persistence workflow workflow-foundation-4 workflowservice

考虑在IIS中运行的WF4项目,其中包含一个工作流定义(xamlx)和一个用于持久性的SqlInstanceStore。 我们不是直接托管xamlx,而是托管一个WorkflowServiceHostFactory,它为每个客户在一个单独的端点上旋转一个专用的WorkflowServiceHost。

这一直运行良好,直到我们需要新版本的工作流程定义,所以现在在Flow.xamlx之上我有Flow1.xamlx。 由于与工作流服务的所有交互都包含有足够智能的业务逻辑来识别所需的版本,因此这个自制的版本控制适用于新启动的工作流(在Flow.xamlx和Flow1.xamlx上)。

但是,在此更改无法重新激活之前已启动工作流(在servicehost引发UnknownMessageReceived异常的帖子上)。 由于WF在告诉您为什么无法重新激活工作流程(错误版本,未找到实例,锁定等)时并不过分冗长,因此我们将SQL事件探查器附加到数据库中。

结果是' WorkflowServiceType' WorkflowServiceHost在其查询中使用的不同于存储的实例' WorkflowServiceType。可能这就是它无法检测到持久化实例的原因。

由于我很确定我使用相同的xamlx,我无法理解这个值来自何处。什么参数用于计算此Guid,环境是否重要(网站名称),以及我可以做些什么来重新激活工作流程?

1 个答案:

答案 0 :(得分:2)

最后我反编译了System.Activities.DurableInstancing。 SqlWorkflowInstanceStore上唯一的WorkflowHostType设置器位于ExtractWorkflowHostType中:

private void ExtractWorkflowHostType(IDictionary<XName, InstanceValue> commandMetadata)
{
    InstanceValue instanceValue;
    if (commandMetadata.TryGetValue(WorkflowNamespace.WorkflowHostType, out instanceValue))
    {
        XName xName = instanceValue.Value as XName;
        if (xName == null)
        {
            throw FxTrace.Exception.AsError(new InstancePersistenceCommandException(SR.InvalidMetadataValue(WorkflowNamespace.WorkflowHostType, typeof(XName).Name)));
        }
        byte[] bytes = Encoding.Unicode.GetBytes(xName.ToString());
        base.Store.WorkflowHostType = new Guid(HashHelper.ComputeHash(bytes));
        this.fireRunnableInstancesEvent = true;
    }
}

我无法清楚地解开调用代码路径,因此我必须在运行时通过将WinDbg / SOS附加到IIS并打破HashHelper.ComputeHash来查找。

我能够检索进入哈希计算的XName,它具有一个等于servicefile的localname,以及一个等于[sitename] / [path] /的命名空间。

最后,WorkflowHostType计算结果为:

var xName = XName.Get("Flow.xamlx.svc", "/examplesite/WorkflowService/1/");
var bytes = Encoding.Unicode.GetBytes(xName.ToString());
var WorkflowHostType = new Guid(HashHelper.ComputeHash(bytes));

底线:显然工作流只能在服务文件名,网站名称和路径完全相同(区分大小写)时才能重新充水