第一个问题:
说我有
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();
}
连接是否已关闭?因为从技术上讲,我们永远不会像我们}
之前那样到达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*/ }
现在,在try
的某个地方说我们收到错误并被抓住了。连接是否仍然关闭?因为我们再次跳过try
中的其余代码并直接转到catch
语句。
我是否对using
的工作原理过于线性思考?即当我们离开Dispose()
范围时,using
是否会被调用?
答案 0 :(得分:170)
无论哪种方式,当退出使用块时(通过成功完成或错误),它将被关闭。
虽然我认为组织这样的 更好 ,因为要看到将要发生的事情要容易得多,即使对于将支持的新维护程序员也是如此它后来:
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*/
}
}
答案 1 :(得分:43)
对这两个问题都是肯定的。 using语句被编译成try / finally块
using (SqlConnection connection = new SqlConnection(connectionString))
{
}
与
相同SqlConnection connection = null;
try
{
connection = new SqlConnection(connectionString);
}
finally
{
if(connection != null)
((IDisposable)connection).Dispose();
}
编辑:将演员表修复为Disposable http://msdn.microsoft.com/en-us/library/yh598w02.aspx
答案 2 :(得分:14)
这是我的模板。从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();
}
}
*修订日期:2015-11-09 *
正如尼克的建议;如果太多的括号让你烦恼,请按照这样的格式......
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();
}
然后,如果您为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(); }
先生......好的。我从我的系统中得到了这个,并且我已经做了一段时间。继续。
答案 3 :(得分:5)
当您离开使用范围时,只会调用Dispose。 "使用"的意图是为开发人员提供有保证的方法,以确保资源得到处置。
来自MSDN:
当达到using语句的结尾或者抛出异常并且控制在语句结束之前离开语句块时,可以退出using语句。
答案 4 :(得分:4)
Using
围绕正在分配的对象生成try / finally,并为您调用Dispose()
。
它可以省去手动创建try / finally块并调用Dispose()
答案 5 :(得分:2)
在第一个示例中,C#编译器实际上将using语句转换为以下内容:
SqlConnection connection = new SqlConnection(connectionString));
try
{
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();
}
finally
{
connection.Dispose();
}
最后语句将始终在函数返回之前被调用,因此连接将始终关闭/处置。
因此,在您的第二个示例中,代码将编译为以下内容:
try
{
try
{
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();
}
finally
{
connection.Dispose();
}
}
catch (Exception)
{
}
将在finally语句中捕获异常并关闭连接。外部catch子句不会看到异常。
答案 6 :(得分:1)
我在 try / catch 块中编写了两个使用语句,我可以看到如果它被放置,异常被捕获了在内部使用语句中,就像ShaneLS example。
try
{
using (var con = new SqlConnection(@"Data Source=..."))
{
var cad = "INSERT INTO table VALUES (@r1,@r2,@r3)";
using (var insertCommand = new SqlCommand(cad, con))
{
insertCommand.Parameters.AddWithValue("@r1", atxt);
insertCommand.Parameters.AddWithValue("@r2", btxt);
insertCommand.Parameters.AddWithValue("@r3", ctxt);
con.Open();
insertCommand.ExecuteNonQuery();
}
}
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.Message, "UsingTest", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
无论放置 try / catch 的位置,都会毫无问题地捕获异常。