Windows Workflow:为什么它们会陷入持久性?

时间:2009-07-29 17:35:51

标签: workflow-foundation

我有一个使用SQL持久性的Windows Workflow实例,由于工作流由ASP.NET表单提交启动,因此在Web运行时中托管。它大部分时间都运行良好,但我注意到我必须要做的事情:

我注意到nextTimer已经过期了,即使是几个小时。有时,持久性数据库中的ownerID和ownedUntil字段为空,有时则不为。 “未锁定”和“已阻止”字段始终为“1”。

...然后工作流运行时不会重新选择它,直到我将“所有者”字段归零,如果它们已经填充并用循环启动应用程序池,那么事情就好了大部分。没有错误(我已经尝试/捕获所有内容的块并写出捕获到跟踪文件中的任何内容),所以不是它。

导致持久性的延迟活动都设置为一分钟,运行时的所有权持续时间也是60秒。它被困在的代码应该总是不到一分钟。

当我写这篇文章时,我很好奇app app / app域的循环是否导致它...当工作流尝试调用运行时中的任何方法时,它正忙着启动app域/池并且可能在60秒的所有权期限内泄漏。这听起来有点合理,会不会使它不能正常补水?

除了那个侧面,可能会导致我看到这种行为的原因是什么?我不想每天通过解开卡住的工作流来照看运行时。

3 个答案:

答案 0 :(得分:7)

应用域回收很可能是您问题的主要部分。 IIS将在最后一个请求完成后立即回收AppDomain。但是,它不会将代码作为该请求的一部分在另一个线程上运行。这是在IIS中托管时使用ManualWorkflowSchedulerService的主要原因之一。但是当您使用活动计时器选项时,它仍然使用后台线程来执行工作流活动。

还要确保在闲置时立即卸载工作流程。最简单的方法是使用SqlWorkflowPersistenceService上的UnloadOnIdle设置。

PersistenceService检查所有权已过期的工作流,但仅在启动时检查。因此,最有可能重新启动IIS工作进程也将重新启动旧工作流而无需任何额外工作。但是因为这是新问题的情况.....只是清除旧的所有权也应该做到这一点。在这种情况下,PersistenceService应该在下次重新加载工作流。唯一的技巧是知道哪个runitme ID是旧的,哪个不是(持有该值的属性不公开)。

要确保的另一件事是重新加载IIS工作进程。如果没有这样做,则没有WF运行时,因此无法检查过期的计时器。听起来你已经覆盖了这个,但以防万一。

答案 1 :(得分:2)

工作流实例被锁定到运行时(因此多个工作流运行时可以共享数据库,而两者都不会处理实例)。当AppDomain回收时,应该停止运行时,导致实例解锁

这可能是多余的,我没有检查,但它有助于解锁工作流实例:

AppDomain.CurrentDomain.DomainUnload += ((sender, args) =>
                                             {
                                                 if (_runtime.IsStarted)
                                                     _runtime.StopRuntime();
                                             });
AppDomain.CurrentDomain.ProcessExit += ((sender, args) =>
                                            {
                                                if (_runtime.IsStarted)
                                                    _runtime.StopRuntime();
                                            });

答案 2 :(得分:1)

您是否检查了数据库和Web服务器上的时钟(如果它们不是同一台服务器)?我之前遇到过与工作流类似的问题,根本原因是数据库和Web服务器时钟不同步。