破棄される前にSQLConnectionをClose()する必要がありますか?


113

Disposableオブジェクトに関する他の質問については、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 2013

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の記事から:

「接続がプールに返されるように、使用が終了したら常に接続を閉じることを強くお勧めします。これは、Connectionオブジェクトの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
MSDNリンクの+1-次の人のように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()ではなく、その逆ではありませんか?

1
通常は両方です。何らかの理由で、CloseがDisposeも呼び出すことを実装することにしました。SqlConnectionの場合、これは大したことではありませんが、StreamWriterを閉じてから破棄すると例外がスローされます。それが今人々が期待するようになったからといって、彼らがその振る舞いを変えることはないと思います。

2

いいえ、Disposeを呼び出す前に接続を閉じる必要はありません。

一部のオブジェクト(SQLConnectionなど)は、Closeを呼び出した後で再利用できますが、Disposeを呼び出した後は再利用できません。他のオブジェクトの場合、Closeの呼び出しはDisposeの呼び出しと同じです。(ManualResetEventとStreamsはこのように動作すると思います)


1

いいえ、SqlConnectionクラスはIDisposableから継承され、(接続オブジェクトの)使用の終了が検出されると、SqlConnectionクラスのDisposeが自動的に呼び出されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.