2014-12-30 18 views
5

Generalnie podążam za wzorcem IDisposable, a dla większości klas jest to uzasadnione. Ale ReaderWriterLockSlim zmusiło mnie do kwestionowania możliwości zastosowania takiego wzoru. Wszystko, co robi ReaderWriterLockSlim.Dispose, zamyka niektóre uchwyty zdarzeń. Jak ważna jest taka klasa z tak małą ilością zasobów? W tym przypadku nie miałbym nic przeciwko, gdyby GC musiał czekać na kolejną rundę, aby finalizatorzy niezarządzanych zasobów mogli dokończyć.W jaki sposób "disposable" to ReaderWriterLockSlim?

Konsekwencja zastosowania wzoru IDisposable jest znaczna, jednak każda klasa korzystająca z klasy jednorazowej musi teraz również wdrożyć IDisposable. W moim konkretnym przypadku implementuję wrapper dla HashSet. Nie spodziewam się w szczególności wymogu pozbywania się takiego obiektu, ponieważ przypadkowo używa on synchronizatora, który to robi.

Czy są jakieś powody, aby nie naruszać wzoru jednorazowego w tym przypadku? Chociaż jestem chętny, nie zrobiłbym tego w praktyce, ponieważ naruszenie spójności jest znacznie gorsze.

+0

Twój problem polega na tym, że używasz niestatycznej blokady, która ma taki sam czas życia jak obiekty? –

+0

@NathanCooper - Z grubsza, tak. Utworzenie blokady dla każdej operacji odczytu/zapisu również nie jest efektywne. Mógłbym użyć 'Monitor', ale martwię się konwojami blokującymi. – toplel32

+0

, więc czytasz coś lub piszesz i nie jest to statyczne? Jest to więc pewien zasób dla każdej instancji. –

Odpowiedz

4

Problem z niezarządzanymi uchwytami systemu operacyjnego jest taki, że handles come from a limited supply. GC nie jest tego świadomy.

Zużycie czystej pamięci klamki nie jest tak duże. Nic więcej niż obiekt w pamięci jądra i prawdopodobnie hash table entry gdzieś.

Masz rację, ponieważ nie wystarczy powiedzieć: "Musisz zawsze zawsze pozbywać się wszystkich przedmiotów jednorazowego użytku". Ta zasada jest zbyt prosta. For example the Task class does not need to be disposed. Jeśli wiesz, co robisz, możesz przyjąć luźniejszą postawę dotyczącą utylizacji. Należy pamiętać, że nie wszyscy członkowie zespołu mogą zrozumieć ten punkt (teraz możesz zostawić link do tej odpowiedzi w kodzie źródłowym ...).

Jeśli masz pewność, że nie wyciekniesz wielu uchwytów, możesz to bezpiecznie zrobić. Należy pamiętać, że w skrajnych warunkach (obciążenie, błędy, ...) może nastąpić wyciek w ilości większej niż przewidywano, powodując problemy z produkcją.

1

Jeśli to pole to staticyou don't need to dispose of it, będzie ono (righty) miało takie samo życie jak aplikacja. Widzę, że nie, przejdźmy dalej.

Prawidłowym sposobem postępowania z IDisposable jest pozbycie się go. Myślę, że potrzebujemy dobrego powodu, aby tego nie robić.

pomocą drugiego zamka:

Myślę, że najlepszym rozwiązaniem jest użycie Monitor lub inny zamek, który będzie miał bonus uproszczenie kodu, jak również. ConcurrentDictionary i inne klasy szkieletowe wydają się stosować to podejście.

Martwisz się o blokadę, ale nie jestem pewna, czy uda się to rozwiązać przez ReaderWriterLockSlim, jedynym realnym rozwiązaniem jest trzymanie mniejszej ilości blokad i przytrzymywanie ich przez krótszy czas.

Nie wyrzucaj:

To wymaga uzasadnienia. Czy możesz tutaj zademonstrować potrzebne korzyści związane z wydajnością?

Jeśli masz kilka przedmiotów, które są długo żywe, dobrze, nie wszystkie materiały jednorazowego użytku są równie ciężkie (to nie jest tak, że pozostawiasz otwarty dokument), prawdopodobnie ujdzie ci to na sucho. Jak zostało wskazane, jaki jest sens pozbycia się wszystkich tych milisekund, zanim aplikacja i tak się zamknie.Wierzę, że destruktor IDisposable ma za zadanie radzić sobie z sytuacjami, w których obiekt nie jest usuwany, chociaż nie można mieć pewności, kiedy, a nawet jeśli jest to wywoływane.

Jeśli masz długowieczną apli kację z wieloma krótkotrwałymi zastosowaniami tej klasy, możesz wpaść w kłopoty. Spiekasz w swoich założeniach dotyczących użycia twojego kodu, po prostu bądź świadomy.

+0

Z "destructor", masz na myśli finalizatora? To prawdopodobnie nie jest konieczne, ponieważ zasoby niezarządzane będą miały samych finalizatorów, więc zrobią to, co wywołałaby metoda dispose. Rozumiem, że 'ReaderWriterLockSlim' zapewnia jedynie korzyści przy wielu gęstych operacjach odczytu, prawda? 'Monitor' prawdopodobnie nie osiągałby gorszych wyników niż to, co próbuję zrobić, ale chcę być bezpieczny w przyszłości. – toplel32

+0

C# destruktory to finalizery .NET. Zwróciłem uwagę, że robią to dla siebie, ... Usuwam ten akapit. Podjęcie decyzji o nierozpuszczeniu spowoduje upieczenie niektórych z twoich założeń (sprawi, że trudniej będzie napisać aplikację o długim czasie użytkowania, która używa ton tych obiektów w krótkim czasie. uchwyty). Podejmowałbym tę decyzję zgodnie z rzeczywistą potrzebą, zamiast przyszłej weryfikacji. –

+0

Tak, stwierdziłem, że gdzieś jest jakaś niejednoznaczność. Mówiąc najprościej, najgorszą rzeczą, jaka może się stać, jest to, że GC musi odłożyć porządek w poszukiwaniu niezarządzanych zasobów, ponieważ musi uruchomić swoich finalizatorów. Co się tyczy wypieku w założeniach, myślę, że tym razem uda mi się uciec. Hans wyjaśnił, że tego rodzaju klasy niekoniecznie konwencjonalne są do tworzenia w dowolnym momencie, nie mówiąc już o mnóstwie razy. – toplel32

Powiązane problemy