2009-05-29 3 views
5

In una classe, ClasseA, ho un oggetto timer. In questa classe registro i gestori di eventi per l'evento trascorso del timer. In un'altra classe, ClassB, ho un gestore di eventi pubblico per l'evento trascorso del timer. Così mi registro l'evento-handler da ClassB in ClasseA come segue:Cosa succede quando un evento si attiva e tenta di eseguire un gestore di eventi in un oggetto che non esiste più?

myTimer.Elapsed += ClassBInstance.TimerElapsed 

Cosa succede se dovessi creare una nuova istanza di ClassBInstance e il timer trascorso evento viene generato quando l'istanza precedente di gestore di eventi di ClassB è ancora legato all'evento trascorso del timer?

Ad esempio:

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

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

risposta

10

per quanto ne so, non è ClassBInstance rifiuti raccolti fino a quando ci sono eventi registrati, perché l'evento contiene un riferimento ad esso.

È necessario assicurarsi di annullare la registrazione di tutti gli eventi di istanze che non sono più in uso.

Importanti sono i casi in cui l'istanza registrata è IDisposable, poiché l'evento può essere generato quando l'istanza viene eliminata. In questi casi ho trovato più facile lasciare che l'istanza si registrasse da sé e annullare la registrazione in Dispose.

+5

Infatti. In particolare, questo è il motivo per cui gli eventi statici sono così pericolosi; è molto facile mantenere vivo un vasto numero di oggetti se non si annulla la sottoscrizione religiosa. Almeno gli eventi di istanza muoiono con l'istanza che detiene il campo di appoggio - ma nessun GC per statica. –

+0

Vale anche la pena ricordare che WPF salta attraverso i cerchi per evitarlo con WeakEvents che IMHO è troppo complicato e ha bisogno di un supporto linguistico. – Josh

2

Se l'istanza precedente è ancora attiva e la nuova istanza ha anche collegato un gestore di eventi, l'evento attiverà entrambi i gestori (uno alla volta). È importante tenere traccia di quando si collegano i gestori di eventi agli eventi, che li si scollega anche quando non sono più necessari. Altrimenti le vecchie istanze continueranno a vivere in memoria, eseguendo gestori di eventi che potrebbero portare a risultati imprevisti.

3

Gli eventi vengono implementati in modo tale che fino a quando il tuo editore è vivo tutti gli abbonati saranno tenuti in vita dall'editore anche se non hai altri riferimenti a questi.

Naturalmente ciò implica anche che è necessario staccare gli abbonati, se si desidera che vengano eliminati indipendentemente dall'editore.

0

È possibile utilizzare il mio WeakEventHandler, basato su WeakReference. Dato che mantiene un riferimento debole al listener di eventi, non costringe l'ascoltatore a vivere.

see this answer

Problemi correlati