线程Windows服务 - Ninject注入DbContext实例生命周期 - 最佳实践?

时间:2013-09-06 13:33:39

标签: multithreading entity-framework ninject dbcontext

我正在构建一个Windows服务,它创建一个每30分钟运行一次的线程,并更新符合条件的某些实体上的几个字段(并且将来,我想添加更多线程来做其他事情,例如每24小时运行一次,每周一次,等等。该服务将使用已经由Web应用程序使用的服务来获取和更新它的数据,并使用Ninject(以及DbContext)注入 - 这一切都可以使用InRequestScope()绑定工作。

但是,我一直在考虑如何使用Windows服务来解决这个问题。本质上,一旦服务启动并创建了线程,它就会连续运行(除了每30分钟休眠一次) - 并且只有在Windows服务停止或进程终止时才会停止。我最初的想法是使用Ninject的InThreadScope()选项注入我的DbContext和服务 - 所以我为每个线程都有一个DbContext。但是,拥有如此长寿命的DbContext通常是一种好习惯吗?这个DbContext可以在那里坐几个星期而不会被处理掉 - 而且我怀疑这不是一个好主意(内存泄漏等)。

但如果没有,那么处理这种情况的最佳方法是什么。每次线程运行时我都可以创建一个新的DbContext,但是如何设置Ninject绑定?目前他们被定义为:

        Bind<IDbContext>().To<EnterpriseDbContext>().InThreadScope();
        Bind<IUserRepository>().To<UserRepository>().InThreadScope();
        // Etc

所以我不完全确定如何构造这个以在线程中创建一个新的。我查看了InTransientScope(),但这导致我的服务使用不同版本的上下文,因此我的更改永远不会被保存。

这似乎是一种常见的情况 - 所以听到其他人的观点会很棒。

2 个答案:

答案 0 :(得分:2)

您可以使用Quartz.Net作为调度机制,而不是创建在下次运行之前休眠的线程。与NamedScope扩展中的InCallScope结合使用时,您具有与WebService的InRequestScope相同的行为。此外,您可以获得优于仅仅生成间隔运行的线程的调度。您可以使用Cron Job语法指定它们何时运行。

见:

答案 1 :(得分:0)

我特别喜欢@ Remo的建议,并将在我工作的下一个项目中尝试这些。但是,我最终通过使用自定义InScope实现解决了这个问题 - 但设置了一个自定义对象,每次线程运行时应该有范围。这样,每次运行时都会重新创建上下文(一旦放置了作用域对象,就会重新设置)。