【问题标题】:Proper way to open and close connection in loop在循环中打开和关闭连接的正确方法
【发布时间】:2018-03-26 07:47:40
【问题描述】:

我有如下代码:

public void Do
{
      using (var myConnection = new SqlConnection(connectionString))
      {
           for (int i = 0; i < 4; i++)
           {
               MyProcess.Execute(myConnection);

           }
           myConnection.Close();
           myConnection.dispose();
      }
}
public class MyProcess
{
     public void Execute(SqlConnection myConnection)
     {
          if (myConnection.State == ConnectionState.Closed)
                myConnection.Open();
          //long running code
     }
}

Execute methods 有时需要 5-10 分钟,有时每次迭代需要 1-2 分钟。

现在我很困惑,我是否应该为每次迭代打开和关闭连接,这将是有效的,还是我是否只打开和关闭连接 1 次。

但是一旦打开和关闭连接,这将为每次迭代保留资源并消耗资源。

所以我没有得到处理这个问题的正确方法

有人可以给我一些建议吗?

【问题讨论】:

  • 次要问题:在using (var myConnection 之后,您不需要明确地.Dispose() 您的连接。由using 处理。
  • 即使代码只需要 100 毫秒,也始终使用 using 语句在 Execute 方法中打开和关闭连接。 Execute-方法是public,你无法控制它的使用。如果您不在Execute 中确保连接,则无法保证已处理连接。连接池将确保没有真正的物理连接必须打开/关闭。
  • @TimSchmelter 那么你是说我应该为每次迭代打开和关闭连接,而不是只打开一次连接?
  • @TimSchmelter - 或将 Execute 方法设为私有/内部。
  • 这也取决于Execute的实现。假设它首先对数据库进行查询,该查询在 100 毫秒内完成。然后对从数据库接收到的数据进行繁重的计算,耗时 2 分钟。在这种情况下,这两个选项都是错误的,您应该在Execute 中打开连接并在您进行数据库查询后立即关闭它,这样它就不会在 2 分钟的繁重计算执行期间保持打开状态。

标签: c# ado.net


【解决方案1】:

ADO.NET 在后台使用Connection Pooling。这就是为什么每次打开新连接都不应该成为问题的原因。您对myConnection.Open() 的调用实际上不会导致每次都打开与数据库的物理连接。

还要检查this question。它的作者对连接打开进行了测量测试。我已经向他展示了随后调用DbConnection.Open() 的时间接近0

使用DbConnection 的最佳方式是在最短的时间内打开它。如果你的MyProcess.Execute() 有很多其他与数据库无关的逻辑需要相当长的时间,你不应该在这个执行过程中保持打开的连接。

查看Best Practices for Using ADO.NET 文章。它有以下明确的声明:

高性能应用程序保持与数据源的连接 使用最少的时间,以及利用 连接池等性能增强技术。

那么 Ado.net 什么时候从连接池中删除连接呢?

This article 提供了一些关于连接池的内部细节:

连接池程序在连接池中删除一个连接后 空闲了大约 4-8 分钟,或者如果 pooler 检测到 与服务器的连接已被切断。请注意,一个被切断的 只有在尝试与之通信后才能检测到连接 服务器。如果找到不再连接的连接 服务器,它被标记为无效。删除无效连接 仅当它们被关闭或回收时才从连接池中。

如果需要,本文还提供了有关池调整的一些详细信息。但是,只有在遇到池化导致的一些性能问题时,才应考虑此类手动配置。

【讨论】:

  • 赞成您为帮助我所做的努力,但请您指出这两种方法之间的区别,以便我能理解首选方式?
  • 即使我通过 close 和 dispose 明确地关闭连接,Ado.net 仍会在我的每次迭代中使用来自连接池的连接?
  • 正确。连接池对应用程序是透明的。即使您关闭或处置(这与关闭基本相同)连接,物理连接仍然保留在池中。
  • 那么 Ado.net 什么时候从连接池中移除连接呢?
  • 我已经更新了我的帖子,回答了这个问题,请检查。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-04
  • 2017-12-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多