0

我有一个托管在 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)

在有人问之前...我摆脱了代码中的每个静态变量、方法和类。没有什么是静态的了。

4

2 回答 2

1

很长一段时间以来,我一直在为类似的问题而苦苦挣扎。我使用 WFW4,当工作流实例长时间延迟时,我发现了类似的错误。

我不知道问题的原因是什么,但我有一个解决方法,您可能会觉得有帮助。

在我的情况下,我得到的错误来自工作流管理服务并说:无法在“net.pipe://.svc”调用服务管理端点来激活服务“/Alerts/Workflows/.xamlx”。例外:“访问被拒绝。”

这些错误在实例进入长时间延迟后的 6 到 30 小时之间的某个时间开始发生。

我发现,如果我在第一个实例延迟并且正在发生错误时创建工作流的新实例,那么工作流管理服务能够恢复与第一个休眠实例的交互。

因此,我创建了一个新的工作流,其唯一目的是定期启动然后终止包含长时间延迟的工作流实例。

使这项工作实际上变得有点复杂。我希望这个新工作流在创建和终止第一个工作流的新实例之间也能进入休眠状态。但是这会导致新工作流的实例遇到与第一个工作流相同的问题。因此,我修改了新的工作流,使其执行以下操作: -- 延迟一段相当短的时间,例如 30 分钟 -- 创建第一个工作流的实例 -- 等待一分钟 -- 终止刚刚创建的第一个工作流程——创建这个新的防错工作流程的新实例——终止

完成此操作后,我不再收到来自工作流管理服务的访问被拒绝错误!

希望这可以帮助

于 2015-04-02T16:59:53.350 回答
0

原来我的第一个答案不正确,但我相信这个答案是正确的,并且解决了 ChrisG 遇到的问题。

我的解决方法实际上并没有奏效。过了一段时间,问题重新浮出水面。准确地说是 29 小时 - 应用程序池回收所需的默认时间。

所以对我来说,解决方案是让我的应用程序池不被回收。当工作流实例处于延迟活动时应用程序池回收时,workflowManagementService 无法唤醒实例并引发访问被拒绝错误。如果您在应用程序池回收后创建工作流的新实例,第一个实例会从中断的地方继续,但有时仍然会出现问题,我相信这就是 ChrisG 的情况。

ChrisG,看着你的可视化,是否有可能在 wf1 睡眠期间 appPool 正在回收?我相信这是异常的原因。如果您在 *2 过去之后启动一个新的 wf 实例(并且如果在 *1 之前发生应用程序池回收),那将唤醒 wf1 和 wf2,但 wf1 将无法正常工作(至少根据我的经验)

此外,这会在 iisreset 和服务器重新启动后发生。要处理这些问题,您需要使用 IIS7,它允许托管 xamlx 文件的 Web 应用程序(以及网站)在 iisreset 或服务器重新启动后自动启动。此选项在 IIS6 中不可用。有关详细信息,请参阅http://www.postseek.com/meta/991815402b369e71ce925cde47ac907d

希望这可以帮助!

于 2015-04-06T13:39:23.910 回答