2

我有一个在 IIS 中运行的 *.xamlx 工作流服务,并且有 State1、State2 和 State3。

Trigger T1 (State 1 -> State 2) listens to "Start" message on Receive Activity.
Trigger T2 (State 2 -> State 3) listens to "Proceed" message on Receive Activity.

我遇到的问题是,当我的状态机处于状态 1 并且“继续”消息即将到来时,我期望出现类似 InvalidOperationException 的情况。但是,它看起来只是在队列中等待并且因超时异常而失败。

我如何在这里获得预期的行为?

4

1 回答 1

1

我只是在这里粘贴我从Jim Carley - MSFT在 MSDN 论坛上得到的答案,这样它就不会在几年后消失。

亚历山大,

您遇到了工作流同时具有“协议书签”和“非协议书签”的情况。“协议书签”由消息传递活动(例如接收)创建。“非协议书签”是与消息传递活动无关的书签。状态活动在内部创建非协议书签。

使用“Pick”时也报告了此问题 - https://social.msdn.microsoft.com/Forums/vstudio/en-US/275f7817-1ec7-433c-89ba-fe48afd1dae8/wf4-wcf-send-message-at -wrong-time?forum=wfprerelease

这是我对该线程的解释的摘录:

使用 Pick 或 State 活动封装 Receive for OperationB 时行为差异(超时)的根本原因是 Pick 和 State 活动创建的内部书签与 Receive 活动创建的书签无关。

接收活动创建的书签(我们称它们为“协议书签”)以特殊方式处理,以保留工作流服务实现的消息传递协议。

想象一个场景,服务具有 Operation1 和 Operation2 的消息“协议”:

接收(操作1)

发送回复(操作 1)

做一些其他的工作

接收(操作2)

发送回复(操作 2)

如果 DoSomeOtherWork 具有可能导致工作流实例空闲的异步操作,它们将创建非协议书签。这些书签将通过工作流服务的消息传递协议之外的其他方式恢复。

因此,Operation1 可以完成,客户端可以在 DoSomeOtherWork 完成之前发送 Operation2。我们不想立即拒绝 Operation2。相反,我们挂在 Operation2 消息上,希望 DoSomeOtherWork 正在完成的工作完成并且与该工作关联的书签被恢复。DoSomeOtherWork 完成后,将创建 Receive(Operation2) 的协议书签,现在可以成功处理来自客户端的消息。

虽然 DoSomeOtherWork 仍然未完成,但收到了操作 2 的消息。它发现 Operation2 没有协议书签。然后,我们检查该实例是否有任何未完成的非协议书签。如果有(就像 DoSomeOtherWork 仍然未完成的情况一样),我们会保留该消息。但是,如果没有其他非协议书签,我们会立即拒绝该消息,因为它是无序的。

从 .NET 4.6 开始,您可以在服务的 web.config 文件中指定一个 AppSetting,用于控制如何处理非协议书签和无序消息。要配置 AppSetting,请将其添加到您的 web.config 文件中:

此“FilterResumeTimeoutInSeconds”的值指定工作流运行时在超时之前挂在无序消息上的时间长度(以秒为单位)。默认值为 60。值为 0 表示它根本不应该等待并拒绝带有错误文本的乱序消息:

此时无法对标识符为“”的服务实例执行“操作”。请确保以正确的顺序执行操作,并且使用中的绑定提供有序的交付保证。

如果该值大于 0,那么在指定的时间到期后仍然会得到超时异常。

同样,这个新的 AppSetting 从 .NET 4.6 开始可用。这一切都假设 BufferedReceive 没有被使用。

这也记录在这里:http: //blogs.msdn.com/b/dotnet/archive/2015/07/20/announcing-net-framework-4-6.aspx ?PageIndex=2

于 2015-08-20T11:22:30.303 回答