C'è un modo semplice per iterare su tutti gli handler abbonati a un determinato evento? Il mio problema è che i clienti si iscrivono ma si dimenticano di annullare l'iscrizione in modo che si verifichi una perdita di memoria. Ho bisogno di un modo per un oggetto per disconnettere tutti i gestori dei suoi eventi nel metodo Dispose in modo che non si verifichi una perdita, almeno non a causa di eventi.C# Come annullare l'iscrizione a tutti i gestori di eventi da un determinato evento?
risposta
Set nulla al vostro evento: MyEvent = null;
Ma è davvero meglio per rendere i clienti cancellarsi dal vostro evento.
Un approccio alternativo consiste nell'utilizzare il cosiddetto modello "delegato debole". Quando si utilizza questa tecnica, l'evento fa riferimento ai client solo utilizzando WeakReference
che non li tiene in memoria. I client verranno raccolti automaticamente quando non vengono più referenziati da altre parti dell'applicazione (e il gestore può anche essere annullato automaticamente quando viene raccolto il client).
Questo è in genere utilizzato per risolvere il problema con i client "dimenticandosi" di annullare l'iscrizione a un evento .NET, quindi sembra che questo potrebbe essere adatto per il tuo problema.
- Dusing Campbell ha un bel article about weak delegates.
- Mi è piaciuto anche questo overview at CodeProject, che discute la maggior parte degli scenari.
- Weak Events vengono utilizzati anche in WPF, ma questo approccio sembra un po 'complicato (per me).
La perdita di memoria si verifica solo se un altro oggetto (listener) muore prima dell'oggetto (origine evento). In questo caso, l'origine evento conserva ancora il riferimento al listener, che impedisce la raccolta del listener. Quando l'origine dell'evento muore, può essere raccolto anche l'ascoltatore non iscritto.
Se l'origine dell'evento muore prima dell'ascoltatore, ciò non impedisce che il listener venga raccolto in seguito, quando tutti gli altri riferimenti ad esso sono impostati su null.
Questo significa che il metodo di eliminazione della fonte di eventi non è corretto per risolvere questo problema. Può essere risolto solo in un codice listener. Semplicemente parlando, non puoi fare nulla, tranne chiedere ai tuoi clienti di scrivere codice pulito.
Al momento della scrittura, la risposta più accurata è la meno popolare.
È possibile annullare l'event handler, ma questo sarebbe comunque rimosso dopo che il suo proprietario è stato rimosso (non è sbagliato essere in ordine, ma come dice Alex, non è dove si trova il problema.
La classe di origine di Adi consentirà di raccogliere gli oggetti in ascolto quando vengono raccolti, non c'è dubbio. Quindi il problema è che l'oggetto sorgente di Adi viene tenuto aperto, probabilmente da una lunga catena di riferimenti nel codice del suo cliente.
Il seguente post sul blog analizza anche una soluzione che Adi sta decifrando e spiega perché non è necessaria.
- 1. Devo annullare l'iscrizione a tutti i gestori di eventi?
- 2. È possibile rimuovere tutti i gestori di eventi di un determinato elemento in javascript?
- 3. Come rimuovere tutti i gestori di eventi Click in Jquery
- 4. C# gestori di eventi personalizzati
- 5. C#: Come interrogare i dettagli di un registro eventi con un determinato ID evento?
- 6. Disattivare temporaneamente tutti i gestori di eventi jQuery attualmente attivi
- 7. È sbagliato non annullare la registrazione dei gestori di eventi?
- 8. Come iniettare i gestori di eventi in eventi con Unity
- 9. Devo annullare l'iscrizione a un evento in un'applicazione metropolitana C#?
- 10. Jquery Rimuovi tutti i gestori di eventi all'interno dell'elemento
- 11. Aggiungi più gestori di eventi per un evento in XAML?
- 12. Overloading gestori di eventi generici a Scala
- 13. C# - funzioni anonime e gestori di eventi
- 14. In che modo i controlli WPF integrati gestiscono i gestori di eventi su un evento collegato?
- 15. C#, gestori di eventi e Threading
- 16. CA1009: dichiarare correttamente i gestori di eventi?
- 17. Quando collegare i gestori di eventi asp.net
- 18. CIO: Cablaggio dipendenze da gestori di eventi
- 19. Convenzioni di reSharper per i nomi di gestori di eventi
- 20. Differenze nell'assegnazione dei gestori di eventi C#?
- 21. Quando entrano in gioco i gestori di eventi di dominio?
- 22. Rimozione gestori di eventi
- 23. Come trovare tutti i sottoinsiemi possibili di un determinato array?
- 24. Registrazione di gestori per evento COM .NET in C++
- 25. Come annullare un evento connesso a un UIButton
- 26. Javascript: come ottenere un elenco dei gestori di eventi legati ad un evento
- 27. I gestori di eventi in JavaScript hanno chiamato in ordine?
- 28. vim: sostituisci tutti i caratteri fino a un determinato token
- 29. I gestori di eventi non sono thread safe?
- 30. jQuery: un modo per "aggiornare" i gestori di eventi?
Non è possibile impostare un evento a null, in C#. –
In realtà è possibile, se ci si trova all'interno della classe in cui è stato dichiarato l'evento. –
Sei corretto. –