SQLConnection이 삭제되기 전에 Close ()해야합니까?


113

Disposable objects에 대한 다른 질문 에 따라 using 블록이 끝나기 전에 Close ()를 호출해야합니까?

using (SqlConnection connection = new SqlConnection())
using (SqlCommand command = new SqlCommand())
{
    command.CommandText = "INSERT INTO YourMom (Amount) VALUES (1)";
    command.CommandType = System.Data.CommandType.Text;

    connection.Open();
    command.ExecuteNonQuery();

    // Is this call necessary?
    connection.Close();
}

답변:


107

using 블록이 있으므로 SQLCommand의 Dispose 메서드가 호출되고 연결이 닫힙니다.

// System.Data.SqlClient.SqlConnection.Dispose disassemble
protected override void Dispose(bool disposing)
{
    if (disposing)
    {
        this._userConnectionOptions = null;
        this._poolGroup = null;
        this.Close();
    }
    this.DisposeMe(disposing);
    base.Dispose(disposing);
}

1
합니까 this._poolGroup = NULL; 연결이 연결 풀로 돌아 오지 않는다는 의미입니까? 그래서 나는 n-1 연결을 가질거야?
Royi Namir

25

.NET Reflector 사용에서 SqlConnection 분해 :

protected override void Dispose(bool disposing)
{
    if (disposing)
    {
        this._userConnectionOptions = null;
        this._poolGroup = null;
        this.Close();
    }

    this.DisposeMe(disposing);
    base.Dispose(disposing);
}

Dispose () 내부에서 Close ()를 호출합니다.


1
@statenjason : 디스어셈블러 라인 .net 리플렉터를 어떻게 활용하는지 말씀해 주시겠습니까?
odiseh 2010

3
@odiseh는 .NET Reflector를 다운로드하고 reflector.exe를 실행하면 모든 .net DLL (표준 라이브러리 포함)을 열 수 있습니다. Visual Studio의 개체 브라우저와 유사한 트리 구조를 제공하지만 클래스 또는 메서드를 마우스 오른쪽 단추로 클릭하고 "분해"를 클릭하면 소스가 C # 또는 VB로 반환됩니다. 옵션.
statenjason 2010

20

using 키워드는 연결을 올바르게 종료하므로 Close에 대한 추가 호출이 필요하지 않습니다.

SQL Server 연결 풀링 에 대한 MSDN 기사에서 :

"연결이 풀로 반환되도록 연결 사용이 끝나면 항상 연결을 닫는 것이 좋습니다. 연결 개체의 Close 또는 Dispose 메서드를 사용하거나 내부의 모든 연결을 열면됩니다. C #에서 문 사용 "

.NET Reflector를 사용한 SqlConnection.Dispose의 실제 구현은 다음과 같습니다.

// System.Data.SqlClient.SqlConnection.Dispose disassemble
protected override void Dispose(bool disposing)
{
    if (disposing)
    {
        this._userConnectionOptions = null;
        this._poolGroup = null;
        this.Close();
    }
    this.DisposeMe(disposing);
    base.Dispose(disposing);
}

1
+1 for MSDN link-나는 다음 사람처럼 reflector \ ILspy를 좋아하지만 문서는 내 답을 찾기 위해 가고 싶은 곳입니다.
mlhDev 2012 년

5

Reflector를 사용하면 의 Dispose메서드가 SqlConnection실제로 호출 하는 것을 알 수 있습니다 Close().

protected override void Dispose(bool disposing)
{
    if (disposing)
    {
        this._userConnectionOptions = null;
        this._poolGroup = null;
        this.Close();
    }
    this.DisposeMe(disposing);
    base.Dispose(disposing);
}


3

아니요, Dispose()어쨌든 Using 블록에서 전화 를 받으면을 (를) 호출 할 필요가 없습니다 Close().


죄송합니다. IDisposable을 구현하고 Close () 메서드가있는 대부분의 개체에서 Close ()를 호출하면 어쨌든 배후에서 Dispose ()를 호출하게됩니다.
Jason Evans

6
가 아니라 다른 주변의 방법이 - Dispose()전화 Close()가 아니라 그 반대?
Town

1
일반적으로 둘 다입니다. 어떤 이유로 그들은 Close가 Dispose를 호출하도록 구현하기로 결정했습니다. SqlConnection의 경우 이것은 큰 문제가 아니지만 StreamWriters는 닫은 다음 폐기하면 예외를 throw합니다. 내 생각 엔 사람들이 지금 기대하는 것이기 때문에 그 행동을 바꾸지 않을 것입니다.

2

아니요, Dispose를 호출하기 전에 연결을 닫을 필요는 없습니다.

SQLConnections와 같은 일부 개체는 Close를 호출 한 후에 다시 사용할 수 있지만 Dispose를 호출 한 후에는 사용할 수 없습니다. 다른 개체의 경우 Close를 호출하는 것은 Dispose를 호출하는 것과 같습니다. (ManualResetEvent 및 Streams는 이와 같이 작동한다고 생각합니다)


1

아니요, SqlConnection 클래스는 IDisposable에서 상속되며 사용 종료 (연결 개체의 경우)가 발생하면 SqlConnection 클래스에서 Dispose를 자동으로 호출합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.