Osobiście włamuję się do uli, jeśli nie umieszczam obiektów ADO, które implementują IDisposable przy użyciu instrukcji. Ale w ramach mojej obecnej umowy stwierdziłem, że ich domowy kod dostawcy danych „dostawca danych” nie 1) implementuje IDisposable i 2) wywołuje Dispose () na czymkolwiek, z czego korzysta, w dowolnym momencie, kiedykolwiek. Użytkownicy bardzo narzekają na problemy z wydajnością w aplikacjach Winforms, które intensywnie używają tego frameworka do dostępu do danych, i chociaż istnieje wiele innych problemów w kodzie, które mogą pogarszać wydajność, ten po prostu krzyczy na mnie i jest bardziej nisko wiszące owoce niż pozostałe.
Więc poza powiedzeniem czegoś takiego: „Pozbywaj się z jakiegoś powodu, użyj tego”, co mogę powiedzieć tym ludziom, aby przekonali ich, że to naprawdę, naprawdę źle?
źródło
Odpowiedzi:
Powiedziałbym, że najlepszą rzeczą, jaką możesz zrobić, to wskazać im Wzorce i praktyki Microsoft dotyczące tego
Dispose()
tematu . Pozwól im zobaczyć pełne konsekwencje niestosowania tego narzędzia, które jest tuż przed nimi.źródło
Jeśli nie wywołasz metody Dispose na połączeniu SQL, po zakończeniu korzystania z niego połączenie NIE zostanie zwrócone z powrotem do puli połączeń.
Jeśli masz problemy z wydajnością, domyślam się, że maksymalna liczba połączeń jest otwarta w bazie danych. DBA może to łatwo potwierdzić.
Najlepsza praktyka firmy Microsoft wymaga, abyś umieścił kod połączenia w instrukcji Using, upewniając się, że połączenie jest usuwane i że połączenie jest zwracane z powrotem do puli.
źródło
Close
jest wystarczające, aby zwolnić pulę połączeń. Pytanie nie mówi, żeClose
nie jest jawnie użyte.Pula połączeń z bazą danych ma ograniczony rozmiar, a jeśli się zapełni, nowe połączenia będą czekać na zwolnienie starych połączeń. Jeśli nie pozbędziesz się ich, gdy tylko z nimi skończysz, zostaną one ostatecznie zwolnione po uruchomieniu finalizatora, ale jest to nieokreślona ilość czasu w przyszłości ... Więc w najlepszym razie zobacz duże opóźnienia przy otwieraniu nowych połączeń.
W najgorszym przypadku mogli wyłączyć pulę połączeń. Być może odkryli, że po pewnym czasie ich aplikacja zwróciła błędy „przekroczenia limitu czasu oczekiwania na połączenie” i wyłączenie puli połączeń „rozwiązało” ten problem. Jest to jednak znacznie gorsze, ponieważ oznacza to, że za każdym razem tworzysz zupełnie nowe połączenie - co zaskakująco wymaga dużych zasobów. Jeśli masz setki połączeń z otwartą bazą danych, nic dziwnego, że widzisz problemy z wydajnością.
Prawidłowym sposobem rozwiązania wszystkich tych problemów jest usunięcie połączenia natychmiast po jego zakończeniu. Najlepiej jest pozostawić połączenie otwarte tak długo, jak to konieczne, i nie dłużej.
źródło
W każdym poważnym zastosowaniu powiedziałbym, że jest całkiem zły. Pozostawienie tych obiektów nie tylko unosi się wokół zabójstwa, ale jest po prostu nieprofesjonalne. Dobrą wiadomością jest to, że Microsoft implementuje Finalize w hierarchii obiektów.
Weźmy
System.Data.SqlClient.SqlConnection
na przykład:Przedmioty zostaną ostatecznie usunięte, ale niedeterministyczna natura powoduje spustoszenie w działaniu.
źródło
Po pierwsze, nie przerywasz połączenia. Więc albo musi to być: a) automatycznie upuszczone, albo b) przejść cyklicznie i zaktualizowane, nawet jeśli klient nie ma z tego powodu żadnego pożytku.
Zakładam, że b) ze względu na opisywane działanie. Jednak nie jest to prawdopodobnie jedyny powód.
MUSISZ zamykać połączenia, najlepiej po stronie klienta, ale musisz także zaimplementować moduł fail-safe po stronie serwera. W przeciwnym razie masz dodatkowe bzdury na tym, że Twój serwer bazy danych musi przetwarzać, dopóki nie zostanie wydany w chwili, gdy Bóg wie.
źródło