2013-03-26 3 views
2

C#에서 "using"블록으로 익숙해 지려고 노력하고 있지만 사용해야하는 시점을 이해하는 데 어려움이 있습니다.저장 프로 시저에 블록 사용

여기에 예가 나와 있습니다. using 블록없이

내 원래의 코드

:

SqlConnection conn = new SqlConnection(cCon.getConn()); 
    SqlCommand cmd = new SqlCommand("sp_SaveSomething", conn); 
    cmd.CommandType = CommandType.StoredProcedure; 
    cmd.Parameters.Add(new SqlParameter("@x", xxx)); 
    cmd.Parameters.Add(new SqlParameter("@ORG", ORG));   
    try 
    { 
     conn.Open(); 
     cmd.ExecuteNonQuery(); 
    } 
    catch (Exception ex) 
    { } 
    finally 
    { 
     conn.Close(); 
    } 

하지만 난 정말이 일을해야 하는가? 아니면 (SqlConnection conn = new SqlConnection(cCon.getConn()))을 사용해야합니까? 이걸 이해하게 도와주세요. 내가 원래 그렇게 잘못하고있는거야?

SqlConnection conn = new SqlConnection(cCon.getConn()); 
    using(SqlCommand cmd = new SqlCommand("sp_SaveSomething", conn)) 
{ 
    cmd.CommandType = CommandType.StoredProcedure; 
    cmd.Parameters.Add(new SqlParameter("@x", xxx)); 
    cmd.Parameters.Add(new SqlParameter("@ORG", ORG));   
    try 
    { 
     conn.Open(); 
     cmd.ExecuteNonQuery(); 
    } 
    catch (Exception ex) 
    { } 
    finally 
    { 
     conn.Close(); 
    } 
} 
+1

이 기사를 읽어야합니다. 그것은 아주 잘 설명합니다; http://msdn.microsoft.com/en-GB/library/yh598w02.aspx. 특히, "using"문이 컴파일러에 실제로 반영된 것을 보여주는 코드 스 니펫을 살펴보십시오. –

+1

try/catch/finally는 iDisposable을 사용하여 객체 내부에서 수행되므로이 ​​상황에서 try/catch/finally를 수행 할 필요가 없습니다. catch/finally를 필요로하는 다른 논리가 있다면 다른 용도로도 사용할 수 있습니다. 그러나이 경우에 당신이하는 일은 기본적으로 처분이 당신을 위해 무엇을 할 것인지를 모방하는 것입니다. 예외적으로 두 번째 코드 예제에서 문제의 오류를 삼키는 것입니다. =) –

답변

10

는하지만 난 그들을 사용해야 힘든 시간을 인식하지 못했습니다.

쉽습니다. IDisposable 인터페이스를 구현하는 클래스를 다룰 때마다 사용해야합니다.

using (SqlConnection conn = new SqlConnection(cCon.getConn())) 
using (SqlCommand cmd = conn.CreateCommand()) 
{ 
    conn.Open(); 
    cmd.CommandText = "sp_SaveSomething"; 
    cmd.CommandType = CommandType.StoredProcedure; 
    cmd.Parameters.Add(new SqlParameter("@x", xxx)); 
    cmd.Parameters.Add(new SqlParameter("@ORG", ORG));   
    cmd.ExecuteNonQuery(); 
} 

하고 싶어 몇 가지 예외를 처리하는 경우는 코드를 포장하면 시도/catch 문에 싶어 처리 할 수있는 : 그냥이 같은

try 
{ 
    using (SqlConnection conn = new SqlConnection(cCon.getConn())) 
    using (SqlCommand cmd = conn.CreateCommand()) 
    { 
     conn.Open(); 
     cmd.CommandText = "sp_SaveSomething"; 
     cmd.CommandType = CommandType.StoredProcedure; 
     cmd.Parameters.Add(new SqlParameter("@x", xxx)); 
     cmd.Parameters.Add(new SqlParameter("@ORG", ORG));   
     cmd.ExecuteNonQuery(); 
    } 
} 
catch (Exception ex) 
{ 
    // do something here with the exception, don't just consume it, 
    // otherwise it's meaningless to catch it 
} 

당신이 (도록 SqlConnection 모든는 IDisposable 자원을 볼 수 있듯이 및 이 코드 스 니펫의 SqlCommand)가 이제 예외가 throw 된 경우에도 올바르게 처리 될 것이라는 것을 보장하는 using 문으로 올바르게 래핑됩니다. 따라서 더 이상 finally 문을 사용하고 명시 적으로이 작업을 수행 할 필요가 없습니다.

ADO.NET은 connection pool을 사용하므로 SqlConnection에서 .Open() 메서드를 호출 할 때 데이터베이스에 대한 실제 연결이 열리지 않습니다. 당신은 단순히 수영장에서 하나를 그리는 것입니다. .Close (또는 .Dispose) 메서드를 호출하면 연결이 닫히지 않습니다. 재사용 할 수 있도록 연결 풀로 반환하는 것입니다.

+0

하지만 conn과 cmd는 모두 일회용입니까? 권리? 어떤 것이 하나의 문장으로 싸여 있습니까? :) –

+1

그들 중 둘 다. 내 대답을 보라. –

+0

감사합니다! 그래서이 경우에는 여전히 conn.Open()을 사용하지만 사용 블록의 끝에 도달하면 자동으로 닫힙니 까? 옳은? –

0

블록을 사용하여 연결하면 연결을 닫지 않아도됩니다. 블록 사용은 IDisposable을 구현하는 개체에 사용됩니다. IDisposable은 개체가 GC에 의해 수집되기 전에 관리되지 않는 리소스를 지울 수있게합니다. 이렇게하면 메모리가 확보되어 GC가 해당 객체를 수집 할 수 있습니다.

0

using 블록은 일회용 개체를 자동으로 닫고 처리하는 try/finally 절일뿐입니다. 내부 try/catch를 추가하면 던져진 예외를 어떤 식 으로든 처리 할 계획 인 경우에만 작동합니다. 귀하의 예제에서 catch 블록에는 아무 것도하지 않으므로 불필요합니다. 코드가

using(SqlConnection conn = new SqlConnection(cCon.getConn()) 
using(SqlCommand cmd = new SqlCommand("sp_SaveSomething", conn)) 
{ 
    cmd.CommandType = CommandType.StoredProcedure; 
    cmd.Parameters.Add(new SqlParameter("@x", xxx)); 
    cmd.Parameters.Add(new SqlParameter("@ORG", ORG));   
    conn.Open(); 
    cmd.ExecuteNonQuery(); 
} 
0

로 변경해야하므로

은 SqlCommand를하고도록 SqlConnection 모두 당신은 SqlConnection 때문에, 실제로, 여기에 블록을 사용하여 몇을 가지고 SqlCommand 모두 IDisposable를 구현해야 일회용이다. 또한 using도 마지막에 연결을 닫으므로 명시적인 conn.Close();이 필요하지 않게됩니다.그것은이 길을 갈 것입니다

using (SqlConnection conn = new SqlConnection(cCon.getConn())) 
    using (SqlCommand cmd = new SqlCommand("sp_SaveSomething", conn)) 
    { 
     cmd.CommandType = CommandType.StoredProcedure; 
     cmd.Parameters.Add(new SqlParameter("@x", xxx)); 
     cmd.Parameters.Add(new SqlParameter("@ORG", ORG)); 
     try 
     { 
      conn.Open(); 
      cmd.ExecuteNonQuery(); 
     } 
     catch (Exception ex) 
     { 
      // Log error, etc. 
     } 
    } 
0

: SqlCommandIDisposable 인터페이스를 구현

using (SqlConnection conn = new SqlConnection(cCon.getConn())) 
{ 
    using (SqlCommand cmd = new SqlCommand("sp_SaveSomething", conn)) 
    { 
     conn.Open(); 
     cmd.CommandType = CommandType.StoredProcedure; 
     cmd.Parameters.Add(new SqlParameter("@x", xxx)); 
     cmd.Parameters.Add(new SqlParameter("@ORG", ORG));   

     cmd.ExecuteNonQuery(); 
    } 
} 

SqlConnection으로 그리고, using 블록은 CloseDispose 방법을 다룰 것입니다.