【问题标题】:Calling Dispose method of a field in OnStop of a Windows service在 Windows 服务的 OnStop 中调用字段的 Dispose 方法
【发布时间】:2019-12-24 06:05:29
【问题描述】:

我开发了一个使用数据库连接的 Windows 服务。

我创建了以下字段:

private MyDBEntities _db;

在 OnStart 中我有:

_db = new MyDBEntities();

然后服务开始工作。

在 OnStop 方法中我有:

_db.Dispose();
_db = null;

这种方法有缺点吗?出于性能原因,我需要在服务运行时始终打开数据库(即 SQL Server)。

谢谢 詹姆

【问题讨论】:

  • 你能给我们一个为什么它应该总是连接的理由吗?为什么只有在使用时才能连接?这可能会让我们更好地了解该做什么。
  • 这是一个对性能非常关键的应用程序。某些外部设备会生成一个由我的服务捕获的事件。在那种情况下,我需要对数据库运行一些查询。不能接受的是每次收到事件,数据库都打开,做任务然后关闭。
  • 这应该不是问题。了解连接池docs.microsoft.com/en-us/dotnet/framework/data/adonet/…
  • 1.如果是这种情况,请删除所有代码并使其成为静态类。如果您要一直保持打开状态,为什么要重新创建所有实体的实例并调用 dispose? 2. 打开连接的性能开销很小,以至于您永远不会注意到。 Myabe 你可以给我们更多的上下文和代码吗?到目前为止,这种方法没有意义。
  • 您无法分析猜测,我们无法审查您不会向我们展示的代码。正如@William 所说,Entity Framework 实现了连接池,因此它不会为每个请求“打开然后关闭”连接。咨询Entity Framework and Connection Pooling,开始编写测试代码。

标签: c# entity-framework-6 windows-services


【解决方案1】:

如果您的服务是访问此数据库的唯一应用,那么它的性能应该不会下降。但是,在我看来,与数据库建立长期连接并不是最好的方法。想象一下,您没有将数据库保存在服务器上,而是使用了一些云提供商(Google、AWS、Azure)。使用云解决方案,您的服务器地址可能不是固定的,并且可能会随着时间而变化。在执行一个查询期间,IP 地址可能会发生变化(很可能,你会得到 SqlTransientException 或类似的,我不记得了)。

如果您的服务将是唯一一个访问数据库的应用,并且您将只有一个实例 - 那么这种方法在性能方面可能是有益的 - 因为您不必总是打开和关闭连接.但是,您必须记住,使用这种方法可能会出现许多其他问题(您可能必须从陈旧的连接重新连接,连接到其他副本实例,或者因为我目前没有考虑的事情而破坏现有连接)。此外,请记住如果您不能正确开发它,这种方法很可能会出现多线程问题。

恕我直言 - 您应该始终在需要时打开与数据库的连接,并在使用后立即关闭。您将避免我之前提到的大多数问题。

【讨论】:

  • 是的......你是对的......我没有想过......这不是唯一使用连接的应用程序。在同一台 PC 和另一台访问同一数据库的 PC 中有一个 Winforms 应用程序。也许我将来会遇到问题。
【解决方案2】:

拥有单例上下文将导致线程锁定SaveChanges()(降低性能)。

此外,每个事件(我假设它是异步运行的)可能会保存一些导致意外行为的其他事件信息。

正如有人已经指出的那样,您可以使用连接池来避免连接问题并在每个触发的请求/事件上处理上下文。

【讨论】:

  • 1) 我不确定是否有人提到 writing 到数据库 2) 没有人提到线程 3) 你 shouldn't be sharing 无论如何都是线程之间的 ORM 上下文 4) 为什么你认为有异步事件吗?
  • @MickyD 只是我的假设
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-05
  • 1970-01-01
  • 1970-01-01
  • 2013-07-20
相关资源
最近更新 更多