2009-05-29 11 views
5

W jednej klasie, ClassA, mam obiekt timera. W tej klasie rejestruję programy obsługi zdarzeń dla zdarzenia, które upłynęło w czasie. W innej klasie, ClassB, mam publiczny event-handler dla upływającego wydarzenia. Więc zarejestrować zdarzeń obsługi z ClassB w ClassA następująco:Co się dzieje, gdy zdarzenie jest uruchamiane i próbuje uruchomić moduł obsługi zdarzeń w obiekcie, który już nie istnieje?

myTimer.Elapsed += ClassBInstance.TimerElapsed 

Co się stanie, jeśli były, aby utworzyć nową instancję ClassBInstance a timer, który upłynął pożary zdarzeń, gdy poprzednia instancja event-przewodnika ClassB jest nadal związane z wydarzeniem, które upłynęło w czasie?

Na przykład:

ClassB classBInstance = new ClassB(); 
myTimer.Elapsed += classBInstance.TimerElapsed 

classBInstance = new ClassB(); 
myTimer.Elapsed += classBInstance.TimerElapsed 

Odpowiedz

10

AFAIK, ClassBInstance nie zbiera śmieci tak długo, jak istnieją zdarzenia zarejestrowane, ponieważ zdarzenie posiada odniesienie do niego.

Musisz się upewnić, że wyrejestrujesz wszystkie zdarzenia, które nie są już używane.

Ważne są przypadki, w których zarejestrowana instancja jest IDisposable, ponieważ zdarzenie może zostać uruchomione, gdy wystąpienie zostanie usunięte. W takich przypadkach najłatwiej było mi pozwolić instancji zarejestrować się i wyrejestrować w Dispose.

+5

Rzeczywiście. W szczególności dlatego statyczne zdarzenia są tak niebezpieczne; bardzo łatwo jest utrzymać przy życiu ogromną liczbę przedmiotów, jeśli nie zrezygnujesz z subskrypcji religijnie. Przynajmniej zdarzenia instancji giną wraz z instancją przechowującą pole zaplecza - ale bez GC dla statystyki. –

+0

Warto również wspomnieć o tym, że WPF przeskakuje przez obręcze, aby tego uniknąć dzięki WeakEvents, których IMHO są zbyt skomplikowane i potrzebują wsparcia w zakresie obsługi niektórych języków. – Josh

2

Jeśli poprzednia instancja nadal żyje, a nowa instancja również podpięła procedurę obsługi zdarzeń, zdarzenie uruchomi oba moduły obsługi (pojedynczo). Ważne jest, aby śledzić, kiedy dołączasz programy obsługi zdarzeń do wydarzeń, a także oddzielasz je, gdy nie są już potrzebne. W przeciwnym razie stare instancje będą nadal żyły w pamięci, wykonując programy obsługi zdarzeń, które mogą prowadzić do nieoczekiwanych rezultatów.

3

Wydarzenia są realizowane tak, że dopóki wydawca żyje, wszyscy subskrybenci będą utrzymywani przy życiu przez wydawcę, nawet jeśli nie masz żadnych innych odniesień do nich.

Oczywiście oznacza to również, że należy odłączyć subskrybentów, jeśli chcesz je wyczyścić niezależnie od wydawcy.

0

Możesz użyć mojego WeakEventHandler, opartego na WeakReference. Ponieważ utrzymuje słabe odniesienie do detektora zdarzeń, nie wymusza na nim działania odbiornika.

see this answer

Powiązane problemy