【问题标题】:Overhead of creating new SqlConnection in c#在 C# 中创建新的 SqlConnection 的开销
【发布时间】:2010-01-07 11:48:02
【问题描述】:

不久前,我为我的 .net 应用程序编写了一个 ORM 层,其中所有数据库行都由 DatabaseRecord 的子类表示。有许多方法,如Load()Save() 等。在我最初的实现中,我在DatabaseRecord 的构造函数中创建了与数据库的连接,例如

connection = new SqlConnection(
    ConfigurationManager.ConnectionStrings["ConnectionName"].ConnectionString
);

然后,我在访问数据库的方法的开头和结尾对该 SqlConnection 调用 Open()Close()。在我看来(作为熟悉编程但对 c# 和 .net 不熟悉的人)这是最有效的做事方式 - 建立一个连接并在课堂内必要时打开/关闭它。

不过,我刚刚读了一些书,似乎在很多地方都推荐了这种模式:

using (var connection = new SqlConnection(...)) {
    connection.Open();
    // Stuff with the connection
    connection.Close();
}

我明白为什么它是可取的 - 即使您在中间执行的操作导致未捕获的异常,连接也会自动为 Dispose()d。我只是想知道像这样多次调用new SqlConnection() 的开销是多少。

连接池已启用,因此我认为开销很小,第二种方法应该是最佳实践,但我只是想确保我的假设是正确的。

【问题讨论】:

  • 感谢所有令人惊讶的快速回答!

标签: c# .net database sqlconnection


【解决方案1】:

是的,这是最佳做法。 using 使您对 Close() 异常安全的调用。

而且创建(任何)对象的开销确实是最小的,对于短期对象(停留在 GC 第 0 代)来说也是最小的。

请注意,您不必再在 using 块的末尾调用 Close(),它会自动为您完成 (Dispose==Close)。

【讨论】:

  • 最小多少?是否有任何基准可以显示打开和关闭连接会损失多少性能?调用 Open 方法时是否会进行网络握手?
  • 其实我觉得这篇文章完美的回答了我的问题。 docs.microsoft.com/en-us/dotnet/framework/data/adonet/…
  • 如果这篇文章是正确的,连接池应该明确地处理握手等,并确保没有不必要的握手发生。
【解决方案2】:

这部分是口味问题。只要您使用连接池,创建新连接(回收池连接)的开销就会很小,因此通常推荐的模式是根据需要创建新的连接对象。

如果您紧接着运行多个命令,那么我认为没有理由为每个命令创建新连接,但您应该避免长时间保持打开连接。

另外,您应该注意Dispose 方法将为您关闭连接。因此无需同时调用CloseDispose。由于using 子句结束时会调用dispose,因此通常不需要调用Close

【讨论】:

    【解决方案3】:

    如果您不确定打开/关闭连接的成本,请将 SqlConnection 设为您的类的成员变量,但将类设为 IDisposable 并在处置该类时处置 SqlConnection

    【讨论】:

    • 其实想多了我觉得这可能是更有效的方法。我在另一个问题中充实了你的建议——如果我理解正确的话,如果你能告诉我,那就太好了:stackoverflow.com/questions/2020576/…
    猜你喜欢
    • 2011-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 2010-10-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多