Dlaczego i jak uniknąć wycieków pamięci obsługi zdarzeń? [zamknięte]

Właśnie zdałem sobie sprawę, czytając kilka pytań i odpowiedzi na StackOverflow, że dodawanie programów obsługi zdarzeń za pomocą += w C# (lub chyba innych językach. Net) może powodować częste wycieki pamięci...

Wiele razy używałem takich programów obsługi zdarzeń i nigdy nie zdawałem sobie sprawy, że mogą one powodować lub powodować wycieki pamięci w moich aplikacjach.

Jak to działa (co oznacza, dlaczego faktycznie powoduje wyciek pamięci)?
Jak mogę rozwiązać ten problem ? Używa -= do tego samego opiekuna wydarzenia wystarczy ?
Czy istnieją wspólne wzorce projektowe lub najlepsze praktyki postępowania w takich sytuacjach ?
Przykład: jak mam poradzić sobie z aplikacją, która ma wiele różnych wątków, używając wielu różnych procedur obsługi zdarzeń do wywołania kilku zdarzeń w interfejsie użytkownika ?

Czy są jakieś dobre i proste sposoby na efektywne monitorowanie tego w już zbudowanej dużej aplikacji?

Author: Vertexwahn, 2010-12-24

3 answers

Przyczyna jest prosta do wyjaśnienia: Gdy subskrybowany jest moduł obsługi zdarzeń, wydawca zdarzenia posiada odniesienie do subskrybenta za pośrednictwem delegata obsługi zdarzeń (zakładając, że delegat jest metodą instancji).

Jeśli wydawca żyje dłużej niż abonent, to utrzyma Abonenta przy życiu, nawet jeśli nie ma innych odniesień do abonenta.

Jeśli anulujesz subskrypcję zdarzenia z równą Obsługą, to tak, to usunie handler i ewentualny przeciek. Jednak z mojego doświadczenia wynika, że rzadko jest to rzeczywiście problem - ponieważ zazwyczaj stwierdzam, że wydawca i abonent mają mniej więcej równe okresy życia.

To jest prawdopodobną przyczyną... ale z mojego doświadczenia wynika, że jest to raczej przesada. Przebieg może się oczywiście różnić... musisz tylko uważać.

 161
Author: Jon Skeet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-24 14:32:51

TAK, -= wystarczy, jednak może być dość trudno śledzić każde przypisane wydarzenie, kiedykolwiek. (szczegóły w poście Jona). Jeśli chodzi o wzorzec projektowy, spójrz na słaby wzorzec zdarzeń .

 12
Author: Femaref,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-26 12:07:54

Zdarzenie jest naprawdę połączoną listą programów obsługi zdarzeń

Kiedy wykonasz + = new EventHandler w zdarzeniu, nie ma znaczenia, czy ta konkretna funkcja została dodana wcześniej jako słuchacz, zostanie dodana raz na+=.

Gdy zdarzenie zostanie wywołane, przechodzi przez linkowaną listę, pozycja po pozycji i wywołuje wszystkie metody (procedury obsługi zdarzeń) dodane do tej listy, dlatego procedury obsługi zdarzeń są nadal wywoływane nawet wtedy, gdy strony nie działają tak długo, jak długo są żywe (zakorzenione), i będą żyć tak długo, jak są podłączone. Tak więc będą wywoływane, dopóki eventhandler nie zostanie odłączony z - = new EventHandler.

Zobacz Tutaj

I MSDN tutaj

 3
Author: TalentTuner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-24 14:47:30