첫 번째 질문 :
내가 가지고 있다고
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);
}
이다 상관없이 시도 / 캐치 배치는, 예외가 문제없이 잡힐 것입니다.