2009-11-27 4 views
22

나는 보통 같은 코드를 사용 관련된 SqlConnection이 삭제되면 SqlCommand.Dispose()가 필요합니까?

using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConn"].ConnectionString)) 
{ 
    var command = connection.CreateCommand(); 
    command.CommandText = "..."; 
    connection.Open(); 
    command.ExecuteNonQuery(); 
} 

가 내 command 자동

을 배치 할 것인가? 또는 아닙니다 그리고 나는 그것을 블록 using으로 싸야합니까? SqlCommand을 처분해야합니까?

+0

Microsoft가 SqlCommand를 구성 요소로 사용하는 것은 나쁘다. 설계자 지원을 위해 Component가 정말로 필요한 경우 IDisposable을 구현하지 않는 가벼운 SqlCommand에 대한 래퍼 일 수 있습니다. –

답변

22

그냥 이렇게 :

using(var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConn"].ConnectionString)) 
using(var command = connection.CreateCommand()) 
{ 
    command.CommandText = "..."; 
    connection.Open(); 
    command.ExecuteNonQuery(); 
} 

너무 나쁜 아무것도하지 않습니다 명령에 처분 호출하지 않습니다. 그러나 Disposal을 호출하면 supress the call to the finalizer이되어 성능 향상을 처리해야합니다.

+11

"명령을 처리하지 않으면 아무 것도 처리하지 못합니다." 사실이지만 익숙해지지는 마세요. 그것은'SqlCommand'에 대해서만 사실입니다. 반면에 'SqlCeCommand'를 삭제하지 않으면 (예 : *) 모바일 장치의 메모리가 매우 빨리 소모됩니다. (그냥 거기에, 그 일을 ...) – Heinzi

+2

'Dispose'는 생성자가 그렇게하므로 finalization을 억제하지 않습니다. –

8

가장 안전한 정책은 명시 적으로 또는 사용 블록을 통해 IDisposable을 구현하는 경우 항상 객체에서 Dispose()을 호출하는 것입니다. 필요하지 않지만 어쨌든 그것을 호출하면 문제가 발생하지 않아야합니다 (클래스가 올바르게 작성된 경우). 또한 구현이 변경 될 수있는 시점을 알 수 없으므로 이전에 호출이 필요하지 않은 부분이 이제는 반드시 필요합니다.

예를 들어, 명령에 블록을 사용하여 여분의 내부를 추가 할 수있을뿐만 아니라 연결에 대해 외부 사용 블록을 유지 관리 할 수도 있습니다.

+2

예, 가장 안전한 정책은 항상 일회용 개체를 처분하는 것입니다 - 특히 * 만든 * 경우! 예를 들어 스트림을 받아들이는 메소드를 작성해 그 메소드 내에 스트림을 배치하는 것은 좋은 생각이 아닙니다. 또 다른주의 사항은 당신은 항상 using 문을 사용하여 처분 할 수 없다는 것입니다. WCF 프록시는 내가 아는 유일한 실제 예입니다. 원격지에서 문제가 발생하고 예외가 발생하면 채널이 닫히고 Dispose가 원래 예외를 대체하는 새로운 예외를 던져 심각한 문제가 될 수 있습니다. –

+1

WCF를 사용하지 않는 또 다른 이유! 팁을 주셔서 감사합니다 ;-) –

1

Reflector을 사용하면 이러한 종류의 물건을 찾을 수 있습니다.

나는 작은 조각을 가지고있다. (나는 열심히 노력하지 않았으므로이 모든 것을 확실히 할 수는 있지만 자신을 파헤칠 것을 제안한다.) 연결을 죽일 때 처분이 없을 때처럼 보인다. 해당 연결과 관련된 모든 자녀의 게다가 명령의 처리가 사실 그렇게 많이하는 것처럼 실제로 보이지 않습니다. 필드를 null로 설정하고 컨테이너에서 분리하여 (관리되는 메모리 누수를 방지 할 수 있음) 이벤트를 발생시킵니다 (중요하지만이 이벤트를 수신하는 사람을 볼 수는 없습니다).

이 방법을 사용하는 블록에서이 항목을 사용하거나 연결을 유지하는 객체에 dispose 패턴을 사용하여 처리하도록하는 것이 좋습니다. (명령을 잠깐 동안 유지하려는 경우).

4

예, 구현이 현재 많이 수행되지는 않지만 미래에 어떻게 변경 될지 잘 모릅니다 (예를 들어 새로운 프레임 워크 버전). 일반적으로 IDisposable을 구현하는 모든 객체를 안전한면에 배치해야합니다. 작업이 지연되고 (asynchroneously 작업을 할 때, 또는 그래서 SqlDataReader 또는 반환 할 때 예를 들어)은 전체 범위를 제어하지 않는 경우

그러나 독자 정도로 그 즉시 CommandBehaviorCloseConnection에 설정할 수 있습니다 작업이 완료되면 연결이 올바르게 닫히거나 처분됩니다.

2

실제로는 Dispose을 건너 뛸 수 있습니다. 자원을 확보하지 않습니다. 생성자가 그렇게 했으므로 finalization을 억제하지 않습니다.

이론적으로 Microsoft는 관리되지 않는 리소스를 보유하도록 구현을 변경할 수 있지만 실제로는 이전에 Component 기본 클래스를 제거하는 API를 사용하기를 바랍니다.