첫 번째 질문 :
내가 가지고 있다고
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범위를 벗어날 때 단순히 호출 됩니까 ?
답변
- 예
- 예.
어느 쪽이든, 사용 블록이 종료되면 (성공적으로 완료되거나 오류로 인해) 닫힙니다.
비록 나중에 지원할 새로운 유지 보수 프로그래머조차도 앞으로 일어날 일을 훨씬 쉽게 알 수 있기 때문에 이렇게 구성하는 것이 더 좋을 것이라고 생각합니다 .
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*/
}
}
답변
두 질문에 모두 그렇습니다. using 문은 try / finally 블록으로 컴파일됩니다.
using (SqlConnection connection = new SqlConnection(connectionString))
{
}
와 같다
SqlConnection connection = null;
try
{
connection = new SqlConnection(connectionString);
}
finally
{
if(connection != null)
((IDisposable)connection).Dispose();
}
편집 : 일회용 캐스트 캐스트
http://msdn.microsoft.com/en-us/library/yh598w02.aspx
답변
여기 내 템플릿이 있습니다. 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 *
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();
}
EA 나 DayBreak 게임을 위해 일한다면 나중에 줄 바꿈을 잊어 버릴 수 있습니다. 내가 맞아? 23이 아닌 1 줄은 내가 더 나은 프로그래머라는 것을 의미합니다.
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(); }
휴 … 좋아. 나는 그것을 내 시스템에서 꺼내어 잠시 동안 나 자신을 즐겁게 해왔다. 계속하십시오.
답변
Dispose는 사용 범위를 벗어날 때 간단히 호출됩니다. “사용”의 목적은 개발자가 리소스를 폐기 할 수있는 보장 된 방법을 제공하는 것입니다.
에서 MSDN :
using 문 끝에 도달하거나 예외가 발생하여 명령문이 종료되기 전에 제어가 문 블록을 벗어나면 using 문을 종료 할 수 있습니다.
답변
Using할당되는 객체 주위에 try / finally를 생성하고 호출 Dispose()합니다.
try / finally 블록을 수동으로 만들고 호출하는 번거 로움을 덜어줍니다. Dispose()
답변
첫 번째 예에서 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 절에서는 예외를 볼 수 없습니다.
답변
try / catch 블록 안에 두 개의 using 문 을 작성했는데 ShaneLS example 과 같이 내부 using 문에 예외가있는 경우 예외가 같은 방식으로 잡히는 것을 볼 수 있습니다 .
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);
}
이다 상관없이 시도 / 캐치 배치는, 예외가 문제없이 잡힐 것입니다.
