İmha edilmeden önce bir SQLConnection'ı Kapatmam () gerekir mi?


113

Tek kullanımlık nesneler hakkındaki diğer soruma göre , bir kullanım bloğunun sonundan önce Close () 'u çağırmalı mıyız?

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();
}

Yanıtlar:


107

Bir using bloğunuz olduğundan, SQLCommand'in Dispose yöntemi çağrılacak ve bağlantıyı kapatacaktır:

// 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
Does this._poolGroup = null; bağlantının bağlantı havuzuna geri dönmediği anlamına mı geliyor? yani n-1 bağlantım olacak?
Royi Namir

25

NET Reflector kullanarak SqlConnection'ın demontajı :

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

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

Dispose () içinde Close () çağırır


1
@statenjason: Disassemblers line .net reflektör kullanımından nasıl yararlanabileceğinizi söyler misiniz?
odiseh

3
@odiseh sadece .NET Reflector'ı indirin, reflektör.exe'yi çalıştırın ve herhangi bir .net DLL dosyasını (standart kitaplık dahil) açabilirsiniz. Size Visual Studio'nun nesne tarayıcısına benzer bir ağaç yapısı sağlar, ancak herhangi bir sınıfa veya yönteme sağ tıklayıp "demonte" seçeneğine tıklayabilirsiniz, daha sonra kaynağı C # veya VB'de (hangisini seçerseniz seçin) size geri döndürür. seçenekler.
statenjason

20

Using anahtar sözcüğü bağlantıyı doğru bir şekilde kapatır, böylece Kapat'a fazladan çağrı gerekmez.

SQL Server Bağlantı Havuzu Oluşturma hakkındaki MSDN makalesinden :

"Bağlantıyı havuza geri döndürmek için, kullanmayı bitirdiğinizde bağlantıyı her zaman kapatmanızı kesinlikle öneririz. Bunu, Bağlantı nesnesinin Kapat veya Dispose yöntemlerini kullanarak veya bir içindeki tüm bağlantıları açarak yapabilirsiniz. C # 'da ifade kullanma "

NET Reflector kullanarak SqlConnection.Dispose gerçek uygulaması aşağıdaki gibidir:

// 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 bağlantısı için +1 - reflektör \ ILspy'yi bir sonraki kişi gibi seviyorum, ancak dokümanlar yanıtlarımı bulmak için gitmek istediğim yer.
mlhDev

5

Reflector kullanarak , Disposemetodunun SqlConnectionaslında çağırdığını görebilirsiniz Close();

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


3

Hayır, Dispose()zaten sizin için Blok aramaları kullanmak , bu yüzden aramanıza gerek yok Close().


Maalesef, IDisposable uygulayan ve Close () yöntemine sahip çoğu nesne için Close () çağrısının sizin için arka planda Dispose () çağrısı yaptığını söylemeliydim.
Jason Evans

6
Bu tam tersi değil mi - Dispose()aramalar Close(), tersi değil mi?
Kasaba

1
Genellikle ikisi de. Bazı nedenlerden dolayı, Close'un Dispose olarak da çağıracağını uygulamaya karar verdiler. SqlConnection için bu önemli bir şey değil, ancak StreamWriters kapatır ve sonra Onları Atarsanız bir istisna atacaktır. Tahminim, bu davranışı değiştirmeyecekler çünkü artık insanların beklediği şey buydu.

2

Hayır, Dispose'u aramadan önce bir bağlantıyı kapatmak gerekli değildir.

Bazı nesneler (SQLConnections gibi) Kapat çağrıldıktan sonra yeniden kullanılabilir, ancak Dispose çağrıldıktan sonra kullanılamaz. Diğer nesneler için Close'u çağırmak Dispose çağırmakla aynıdır. (ManualResetEvent ve Streams bence böyle davranıyor)


1

Hayır, SqlConnection sınıfı IDisposable öğesinden miras alır ve kullanımın sonu (bağlantı nesnesi için) ile karşılaşıldığında, SqlConnection sınıfında otomatik olarak Dispose çağırır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.