我有一个托管在 IIS 下并使用 AppFabric 1.1 的 WCF Windows 工作流 (4.5) 工作流服务。工作流实例运行时间很长(最多大约一周),但大部分时间都花在了延迟活动上。
起初这似乎工作正常,但是当同时运行工作流的多个实例时(超过 2 个实例会导致这种情况),其中一些在延迟步骤期间从内存中卸载后就永远不会醒来。当我查看日志时,我发现的错误都是这样的:
System.OperationCanceledException: The execution of InstancePersistenceCommands has been canceled because the InstanceHandle was freed.
at System.Runtime.AsyncResult.End[TAsyncResult](IAsyncResult result)
at System.ServiceModel.Activities.Dispatcher.DurableInstanceManager.WaitAndHandleStoreEventsCallback(IAsyncResult result)
不幸的是,我没有找到有关该错误消息的任何有用信息。
AppFabric 持久实例表中的 SuspensionExceptionName 和 SuspensionReason 字段显示 System.NullReferenceException:对象引用未设置为对象的实例。但这不会发生在我的工作流程内部,只会发生在外部。
附加信息:
- 我将活动作为 Fire & Forget 运行(接收活动,不发送)
- 我的工作流调用其他 WCF 服务来获取数据。
- 我在 Server 2012 R2、IIS 8(不是天蓝色)上运行它
- 工作流持久性正在工作。我可以重置 IIS,重新启动......它只是在我运行 2 个实例时出现问题。
- 我绝对没有达到任何限制。虽然工作流处理几 MB 的数据,但此问题发生在 2 个以上的实例上。
知道这里可能会发生什么吗?
编辑:我意识到我找到了有关问题如何运作的更多信息,但从未将其添加到问题中。当延迟问题发生时,它的操作很像一个由 2 个线程写入的静态变量。
这是一个可视化:
WF1 Start ---->Do Stuff--->Sleep------------*1----->Cancelled Exception at some point
------WF 2 Start---->Do Stuff------->Sleep->Wake up---------*2------>More Stuff---->End Successfully
*1 - When WF Instance 1 Should Wake up (Same time as WF 2 wakes)
*2 - When WF Instance 2 Should have woken up (Seems to be ignored)
在有人问之前...我摆脱了代码中的每个静态变量、方法和类。没有什么是静态的了。