Devo sempre disconnettere i gestori di eventi nel metodo Dispose?

Sto lavorando in C # e il mio posto di lavoro ha degli standard di codice. Uno di questi è che ogni gestore di eventi che colleghiamo (come KeyDown ) deve essere disconnesso nel metodo Dispose . C’è qualche buona ragione per quello?

A meno che non si aspetti che l’editore dell’evento sopravviva al sottoscrittore, non c’è motivo di rimuovere il gestore di eventi, no.

Questo è uno di quegli argomenti in cui la tradizione popolare è cresciuta. Hai davvero bisogno di pensarci in termini normali: l’editore (ad esempio il pulsante) ha un riferimento al sottoscrittore. Se sia l’editore che il sottoscrittore saranno idonei per la raccolta dei rifiuti allo stesso tempo (come è comune) o se il publisher sarà idoneo per la garbage collection in precedenza , non si verificherà alcun problema con il GC.

Gli eventi statici causano un problema di GC perché sono effettivamente un editore a vita infinita – scoraggerei gli eventi statici interamente, ove ansible. (Raramente li trovo utili).

L’altro ansible problema è se si desidera interrompere esplicitamente l’ascolto degli eventi perché l’object si comporta in modo anomalo se l’evento viene generato (ad esempio, proverà a scrivere su un stream chiuso). In tal caso, sì, dovresti rimuovere il gestore. È più probabile che sia nel caso in cui la tua class implementa già IDisposable . Sarebbe inusuale, anche se non imansible, che valga la pena implementare IDisposable solo per rimuovere i gestori di eventi.

Ho avuto una perdita GDI importante nella mia applicazione se non avessi annullato la registrazione dei gestori di eventi in Dispose () di un controllo utente che veniva creato e distrutto dynamicmente. Ho trovato il seguente nella guida di Visual Studio 2013, nella Guida alla Programmazione C #. Nota le cose che ho messo in corsivo:

Come: iscriversi e annullare l’iscrizione agli eventi

… snip …

Cancellazione, cancellami

Per impedire che il gestore eventi venga richiamato quando l’evento viene generato, annullare l’iscrizione all’evento. Per evitare perdite di risorse, è necessario annullare l’iscrizione agli eventi prima di smaltire un object sottoscrittore. Finché non si annulla l’iscrizione a un evento, il delegato multicast che è alla base dell’evento nell’object di pubblicazione ha un riferimento al delegato che incapsula il gestore di eventi dell’abbonato. Finché l’object di pubblicazione detiene tale riferimento, la garbage collection non cancellerà il tuo object di sottoscrizione.

Si noti che nel mio caso sia l’editore che il sottoscrittore erano nella stessa class e che i gestori non sono statici.