在"使用"块中是SqlConnection在返回或异常时关闭?

Mar*_*cus 134 c# using sqlconnection

第一个问题:
说我有

using (SqlConnection connection = new SqlConnection(connectionString))
{
    connection.Open();

    string storedProc = "GetData";
    SqlCommand command = new SqlCommand(storedProc, connection);
    command.CommandType = CommandType.StoredProcedure;
    command.Parameters.Add(new SqlParameter("@EmployeeID", employeeID));

    return (byte[])command.ExecuteScalar();
}
Run Code Online (Sandbox Code Playgroud)

连接是否关闭?因为从技术上讲,我们永远不会}return以前那样到达最后.

第二个问题:
这次我有:

try
{
    using (SqlConnection connection = new SqlConnection(connectionString))
    {
        int employeeID = findEmployeeID();

        connection.Open();
        SqlCommand command = new SqlCommand("UpdateEmployeeTable", connection);
        command.CommandType = CommandType.StoredProcedure;
        command.Parameters.Add(new SqlParameter("@EmployeeID", employeeID));
        command.CommandTimeout = 5;

        command.ExecuteNonQuery();
    }
}
catch (Exception) { /*Handle error*/ }
Run Code Online (Sandbox Code Playgroud)

现在,说出来try我们得到一个错误,它被抓住了.连接是否仍然关闭?因为我们再次跳过其余代码try并直接转到catch语句.

我是否在思考如何using运作?即Dispose()当我们离开using范围时,是否只是被调用?

Dav*_*vid 173

  1. 是.

无论哪种方式,当退出使用块时(通过成功完成或错误),它将被关闭.

虽然我认为这样组织会更好,因为要看到将要发生的事情要容易得多,即使对于稍后会支持它的新维护程序员来说也是如此:

using (SqlConnection connection = new SqlConnection(connectionString)) 
{    
    int employeeID = findEmployeeID();    
    try    
    {
        connection.Open();
        SqlCommand command = new SqlCommand("UpdateEmployeeTable", connection);
        command.CommandType = CommandType.StoredProcedure;
        command.Parameters.Add(new SqlParameter("@EmployeeID", employeeID));
        command.CommandTimeout = 5;

        command.ExecuteNonQuery();    
    } 
    catch (Exception) 
    { 
        /*Handle error*/ 
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 问题:使用Using语句时是否需要打开连接? (10认同)
  • @ Fernando68是的,你还是要打开连接.`using`只保证调用对象的`Dispose`方法. (8认同)
  • @TrueWill - 我同意.我只是为了结构而移动了一些代码. (3认同)
  • 此外,如果您正在使用事务,通过在`using`中使用`try catch`,您可以在`catch`中明确地显示`.Commit`或`.Rollback`事务.这更具可读性和显式性,并允许您在给定异常类型的情况下提交.(如果未提交,则事务隐式回滚到`conn.Close`.). (3认同)

Rya*_*sen 45

这两个问题都是.using语句被编译成try/finally块

using (SqlConnection connection = new SqlConnection(connectionString))
{
}
Run Code Online (Sandbox Code Playgroud)

是相同的

SqlConnection connection = null;
try
{
    connection = new SqlConnection(connectionString);
}
finally
{
   if(connection != null)
        ((IDisposable)connection).Dispose();
}
Run Code Online (Sandbox Code Playgroud)

编辑:将演员表修复为Disposable http://msdn.microsoft.com/en-us/library/yh598w02.aspx


Sha*_*eLS 17

这是我的模板.从SQL服务器中选择数据所需的一切.关闭并处理连接,并捕获连接和执行中的错误.

string connString = System.Configuration.ConfigurationManager.ConnectionStrings["CompanyServer"].ConnectionString;
string selectStatement = @"
    SELECT TOP 1 Person
    FROM CorporateOffice
    WHERE HeadUpAss = 1 AND Title LIKE 'C-Level%'
    ORDER BY IntelligenceQuotient DESC
";
using (SqlConnection conn = new SqlConnection(connString))
{
    using (SqlCommand comm = new SqlCommand(selectStatement, conn))
    {
        try
        {
            conn.Open();
            using (SqlDataReader dr = comm.ExecuteReader())
            {
                if (dr.HasRows)
                {
                    while (dr.Read())
                    {
                        Console.WriteLine(dr["Person"].ToString());
                    }
                }
                else Console.WriteLine("No C-Level with Head Up Ass Found!? (Very Odd)");
            }
        }
        catch (Exception e) { Console.WriteLine("Error: " + e.Message); }
        if (conn.State == System.Data.ConnectionState.Open) conn.Close();
    }
}
Run Code Online (Sandbox Code Playgroud)

*修订:2015-11-09*
按照NickG的建议; 如果太多的括号让你烦恼,那就像这样格式......

using (SqlConnection conn = new SqlConnection(connString))
   using (SqlCommand comm = new SqlCommand(selectStatement, conn))
   {
      try
      {
         conn.Open();
         using (SqlDataReader dr = comm.ExecuteReader())
            if (dr.HasRows)
               while (dr.Read()) Console.WriteLine(dr["Person"].ToString());
            else Console.WriteLine("No C-Level with Head Up Ass Found!? (Very Odd)");
      }
      catch (Exception e) { Console.WriteLine("Error: " + e.Message); }
      if (conn.State == System.Data.ConnectionState.Open) conn.Close();
   }
Run Code Online (Sandbox Code Playgroud)

再说一次,如果您在EA或DayBreak游戏中工作,您也可以放弃任何换行符,因为这些只适用于那些必须回来查看您的代码且真正关心的人?我对吗?我的意思是1行而不是23行意味着我是一个更好的程序员,对吧?

using (SqlConnection conn = new SqlConnection(connString)) using (SqlCommand comm = new SqlCommand(selectStatement, conn)) { try { conn.Open(); using (SqlDataReader dr = comm.ExecuteReader()) if (dr.HasRows) while (dr.Read()) Console.WriteLine(dr["Person"].ToString()); else Console.WriteLine("No C-Level with Head Up Ass Found!? (Very Odd)"); } catch (Exception e) { Console.WriteLine("Error: " + e.Message); } if (conn.State == System.Data.ConnectionState.Open) conn.Close(); }
Run Code Online (Sandbox Code Playgroud)

嗯......好的.我从我的系统中得到了这一点,并且我已经做了一段时间.继续.

  • 您是否知道可以使用语句进行堆叠而无需额外的括号?删除最后一个大括号,然后将using语句放在彼此旁边:) (6认同)

ove*_*ood 5

当您离开使用范围时,只会调用Dispose."使用"的目的是为开发人员提供有保证的方法来确保资源得到处置.

来自MSDN:

当达到using语句的结尾或者抛出异常并且控制在语句结束之前离开语句块时,可以退出using语句.


Voo*_*ild 5

Using围绕所分配的对象生成一个try / finally并Dispose()为您调用。

它免除了您手动创建try / finally块并调用的麻烦 Dispose()