我只是在这里粘贴我从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