EF6、Windows 服务和数据库轮询

Posted

技术标签:

【中文标题】EF6、Windows 服务和数据库轮询【英文标题】:EF6, Windows Service & Database polling 【发布时间】:2014-04-01 06:48:31 【问题描述】:

我有一个轮询数据库的 Windows 服务。我正在使用 EF6 和 linq 进行查询和更新等。

轮询需要尽可能频繁,可能每 2 秒一次或在该区域内的某个时间。

我的直觉告诉我要有一个连接并在我的服务运行时保持打开状态,但是别的东西告诉我每次都打开和关闭连接。我觉得后者会减慢它(这真的会减慢这么多吗?)。

在 Windows 服务中轮询数据库的最佳做法是什么?我真的应该如此频繁地轮询我的数据库吗?

【问题讨论】:

【参考方案1】:

我认为您应该经常处理上下文并在每次轮询数据库时创建一个新上下文。

主要原因是除非你禁用对象跟踪(实际上只适用于只读操作),否则上下文会随着时间的推移变得越来越大,每次连续的轮询操作都会将更多数据加载到上下文的缓存中。除了这会导致内存增加之外,SaveChanges() 也会变慢,因为 ObjectContext 然后会查找附加到它的对象中的更改。

如果连接因任何原因丢失,您也很难将新连接与上下文相关联。无论如何,根据我自己的经验,它不会减慢任何速度,在第一个之后构造任何 EF 上下文对象都很快,因为模型在第一次加载时被缓存。

我不会担心每 2 秒的每次轮询。这对我来说似乎完全合理。

顺便说一句,如果您使用的是 SQL Server,则可以使用 Sql Dependency 在数据更改时触发事件,但轮询是最可靠的选项。

http://msdn.microsoft.com/en-us/library/62xk7953(v=vs.110).aspx

或者,如果您不喜欢轮询,您可以考虑使用 RabbitMQ 之类的 Message Broker 系统并更新您的应用程序以使用它,但要准备好浪费几周的时间来实施基础架构。

【讨论】:

感谢您向我指出 SQL 依赖项,它确实看起来非常有用。您能否详细说明为什么它不可靠?你也用过实体框架吗? 我在生产环境中看到了 SQL 依赖连接丢失且事件未触发的实例。它有点像 FileSystemWatcher,因为值得用不那么频繁的轮询来支持它,并经常重新创建 SQL 依赖项/观察程序。我没有将它与实体框架一起使用。如果您正在编写 Windows 服务或其他东西,它可能会连续几个月无人看管,有时没有人注意到它是否默默地停止工作(即服务没有“停止”,但它也没有做任何事情!),所以我喜欢涵盖所有基础。

以上是关于EF6、Windows 服务和数据库轮询的主要内容,如果未能解决你的问题,请参考以下文章

MVC5中EF6 Code First启动慢及间隙变慢的一些优化处理

Windows 服务任务 - 轮询取消

套接字,轮询,无套接字结果?

从 Windows 打印服务器轮询打印机信息

使用 Windows 服务进行轮询

连接更新数据库命令的EF6问题