Ne kadar kötü Dispose () SqlConnections değil mi?


14

Şahsen, ifadeleri kullanırken IDisposable uygulayan ADO nesneleri koymazsam kovanlarda ayrılırım. Ama benim mevcut sözleşmede, kendi kurumsal kurumsal çerçeve "veri erişim sağlayıcısı" kodu 1) IDisposable uygulamak ve 2) herhangi bir noktada, kullandığı herhangi bir şey üzerinde Dispose () çağırmak bulduk. Kullanıcılar, veri erişiminde bu çerçeveyi yoğun şekilde kullanan Winforms uygulamalarındaki performans sorunları hakkında çok fazla şikayet ediyorlar ve kodda performansa çarpabilecek başka bir çok sorun olsa da, bu sadece bana çığlık atıyor ve daha fazlası diğerlerine göre düşük asılı meyve.

Öyleyse, "Bir sebepten ötürü bertaraf et, kullan," gibi bir şey söylemenin ötesinde, bu insanlara bunun gerçekten, gerçekten kötü olduğuna ikna etmelerini ne söyleyebilirim?


5
Heh .. benim tahminim, bir noktada ikna etmeye gerek kalmayacak :)
dr Hannibal Lecter

Yanıtlar:


6

Yapabileceğiniz en iyi şeyin onları Microsoft'un Dispose() burada bulunan Desen ve Uygulamalarına yönlendirmek olduğunu söyleyebilirim . Önlerinde bulunan bu aracı kullanmamanın tüm sonuçlarını görsünler.


1
Sadece üstte "bu emekli içerik" diye bağırmayacak bir sürüm bulabilseydim.
AJ Johnson

Bilirsin, gözlerim bunun üzerine parladı. Ancak şimdi dikkatlice okuduğumda, insanların o sayfadan emekli olan "hala kullanıyor olabilecekleri" merak ediyorum. Belki CAS?
Jesse C. Slicer

Daha yakından tararken, bunların çoğu hala benim için alakalı görünüyor. Neden emekli olarak işaretlendiğinden emin değilim.
AJ Johnson

10

SQL Bağlantısında Dispose yöntemini çağırmazsanız, bunu yaptığınızda, bu bağlantı bağlantı havuzuna geri döndürülmez.

Performans sorunları yaşıyorsanız, tahminim maksimum bağlantıların veritabanınızda açılmasıdır. Bir DBA bunu kolayca teyit edebilir.

Microsoft'un En İyi Uygulaması, bağlantınızın atılmasını ve bağlantının havuza geri döndürülmesini sağlayarak bağlantı kodunuzu bir Using deyiminin içine yerleştirmenizi ister.


CloseBağlantı havuzuna geri dönmek için çağrı yeterlidir. İbaresi taşımayan soru Closedeğildir açıkça kullandı.
user2864740

9

Veritabanı bağlantı havuzunun boyutu sınırlıdır ve doldurulursa, yeni bağlantılar eski bağlantıların serbest bırakılmasını bekler. Onları bitirir bitirmez atmazsanız, sonlandırıcı çalıştığında sonunda serbest bırakılırlar, ancak bu gelecekte belirsiz bir süre ... Yani en iyi ihtimalle, yeni bağlantılar açarken uzun gecikmelere bakın.

En kötüsü, bağlantı havuzunu devre dışı bırakmış olabilirler. Belki de bir süre sonra uygulamalarının "bağlantı için bekleyen zaman aşımı" hataları döndürdüğünü ve bağlantı havuzunu devre dışı bırakmanın bu sorunu "çözdüğünü" keşfettiler. Ancak, bu çok daha kötüdür, çünkü her seferinde tamamen yeni bir bağlantı oluşturduğunuz anlamına gelir - bu şaşırtıcı derecede kaynak yoğundur. Veritabanına açık yüzlerce bağlantınız varsa, performans sorunlarını görmeniz şaşırtıcı değildir.

Tüm bu sorunları çözmenin doğru yolu, bağlantınızı bitirir bitmez atmaktır. En iyi fikir, bağlantıyı tam olarak gerektiği kadar açık tutmaktır ve artık değil.


1
Hatta bundan biraz daha kötü. Havuz yeterince yedeklenirse, yönetim araçlarından bağlantı girişimleri de dahil olmak üzere birçok bağlantı denemesi sonuçta başarısız olur ve veritabanımızı etkili bir şekilde kilitleyebilirsiniz.
Joel Coehoorn

3

Herhangi bir ciddi uygulamada oldukça kötü olduğunu söyleyebilirim. Bu nesneleri sadece öldürme performansı etrafında yüzmekle kalmaz, aynı zamanda profesyonelce de değildir. İyi haber, Microsoft'un nesne hiyerarşisinde Finalize uygulamasını gerçekleştirmesidir.

~Object()
{
    this.Dispose(false);    
}

public void Dispose()
{
    this.Dispose(true);
    GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
    // ...
}

Al System.Data.SqlClient.SqlConnectionörneğin:

System.ComponentModel.Component <- Atma işlemini sonlandır desenini uygular.
    |
System.Data.Common.DbConnection
    |
System.Data.SqlClient.SqlConnection

Nesneler nihayetinde bertaraf edilecektir, ancak deterministik olmayan doğa performansa zarar vermektedir.


0

Birincisi, bağlantıyı sonlandırmıyorsunuz. Bu yüzden ya a) otomatik olarak bırakılır ya da b) İstemcinin bir faydası olmasa bile, dolaşıp güncellenir.

Ben kabul ediyorum ) b performansı Tarif ettiğiniz vurmak nedeniyle. Ancak, tek nedeni bu değildir.

Bağlantılarınızı, tercihen istemci tarafında kapatmalısınız ZORUNLU, ancak sunucu tarafında da bir arıza kasası uygulamalısınız. Aksi takdirde, veritabanı sunucunuzun god-knows-when'de yayınlanıncaya kadar işlemesi gerektiğine dair ekstra bok var.

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.