【问题标题】:Close SqlConnection in the Finally when using "Using"使用“使用”时在最后关闭 SqlConnection
【发布时间】:2011-04-06 09:03:53
【问题描述】:

我想在最后关闭 SqlConnection,因为使用并没有真正关闭它并且连接池已满。但我不知道什么是正确的方法,因为 conn 对象在 finally 部分中不再可访问。

try 
{
    using (var conn = new SqlConnection(_dbconnstr)) 
    {
        //...
    }
}
catch (Exception ex)
{
    //...
}
finally 
{
    conn.Close //?!?!?!?!???
}

【问题讨论】:

  • 您还有其他问题。 using 在内部实现为 try/finally 对,在 finally 块中调用 Dispose。对于SqlConnectionCloseDispose 是可以互换的。
  • 作为答案,我建议您检查有关 DataReaders 的相同内容:您关闭 Connection 的方式没问题。
  • 哦,我完全忽略了完整的 Using 块位于 try{ } 块中的观点。我误读了这一点,因为括号的缩进方式很奇怪。

标签: c# .net sql


【解决方案1】:
using (var conn = new SqlConnection(_dbconnstr)) 
{
    //code
}

扩展为:

SqlConnection conn = new SqlConnection(_dbconnstr);
try
{
    //code
}
finally
{
    conn.Dispose();
}

所以你应该处理错误,但你可以忘记关闭连接。

【讨论】:

  • (一个小问题:你的展开是不正确的。如果构造函数抛出,那么在finally块中调用Dispose的尝试也会抛出NullReferenceException并隐藏真正的错误。编译器实际上将赋值放在try 块之外,然后在调用Dispose 之前也在finally 块中执行空检查。)
  • @LukeH NullReferenceException 不会被抛出,因为分配是在 try 锁之前。因此,如果构造函数失败,则执行不会进入 try..finally 块。
【解决方案2】:

您无需在 finally 块中关闭 connusing 块将为您处理关闭连接。 (实际上,在这种情况下,您可能根本不需要try...finally,除非您在finally 中有其他需要处理的资源。)

using 块将转换为如下内容:

var conn = new SqlConnection(/*...*/);
try
{
    // ...
}
finally
{
    if (conn != null)
        ((IDisposable)conn).Dispose();
}

SqlConnection 对象的Dispose 方法将在finally 块中调用,Dispose 方法继续为您调用Close

【讨论】:

  • 总是在 try 块内初始化。
  • @Claus:我只是在解释编译器生成的内容,它会立即在try之前 执行分配,正如我所展示的那样。你应该在投票之前检查你的事实!
【解决方案3】:

在对象上退出 using 块调用 .Dispose(),因为 SqlConnection 将关闭连接和所有打开的资源。

因此不需要tryfinally 块。

【讨论】:

  • 这是不正确的。如果系统想要做一些错误的事情,就需要 try 块。例如,记录有时在调试模式下非常有用的异常消息。
【解决方案4】:

AFAIK,以下 using 语句:

using (var conn = new SqlConnection(_dbconnstr)) 
{

}

相当于:

SqlConnection conn;
try
{
    //`using` scope operations are executed here
    conn = new SqlConnection(_dbconnstr));

}
catch
{
    //exceptions are bubbled
    throw;
}
finally
{
    //Dispose is always called
    conn.Dispose();
}

【讨论】:

  • 错了。等效于: var conn = new SqlConnection(_dbconnstr); { ... } conn.Dispose();它与 try/catch 无关。 {} 表示 C# 中的范围。
  • @Claus Jørgensen:那么这意味着您对这个问题的几乎每个答案都是错误?错误的。它确实与(至少)try / finally一切有关。
  • 不,只有大约一半。 (另请注意评论已更新)
  • @Claus Jørgensen:您的第一条评论没有意义 - 只是新建一个实例并期望能够到达 Dispose 调用 不是 @987654325 @ 有效:using 保证 Dispose 将被调用,这发生在 finally 块内。
【解决方案5】:

据我了解,连接对象的 Dispose() 方法将关闭连接。您无需显式调用 Connection.Close。

【讨论】:

  • 在内部处理调用 .Close() 。不同之处在于它在处理后无法重新打开。
  • 确实如此。我没有想到这一点。但是如果我们使用“using”关键字,那么调用 Connection.Close() 没有意义吗?
【解决方案6】:

您关闭与Using 的连接的方式没问题。也许您可能忘记关闭一些 DataReader 了?

【讨论】:

    猜你喜欢
    • 2014-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-23
    相关资源
    最近更新 更多