| 

.NET C# Java Javascript Exception

9
Hallo zusammen,

ich habe eine Verständnisfrage zu Lambda Expressions in Zusammenhang mit EventHandlern.

"Herkömliche" EventHandler als Methoden einer Instanz müssen ja wieder deregistriert werden. Zum Beispiel wenn auf ein FormClosed-Event reagiert wird.

private void DlgFormClosed(Object sender, FormClosedEventArgs e)
{
this.myIsDlgActive = false;
}

// registrierung
dlg.FormClosed += DlgFormClosed;

// wenn der EventHandler nicht mehr benötigt wird: deregistrierung
dlg.FormClosed -= DlgFormClosed;


Andernfalls existiert weiterhin eine Referenz auf das entsprechende dlg-Objekt.

Wie ist es nun, wenn statt dem EvetnHandler ein Delegate ala Lambdaausdruck verwendet wird?

dlg.FormClosed = (s, e) => this.myIsDlgActive = false;


Muss dieses ebenfalls deregestriert werden? Und wenn ja, wie würde die deregistrierung aussehen?

Danke im voraus!
News:
05.08.2011
Tachyon 690 1 7
Tachyon 690 1 7
2 Antworten
9
Hallo Tachyon,

ja, du musst ihn wieder abmelden. Der Lambdaausdruck ist ja nur syntactic sugar, um anonyme Methoden zu inlinen, aus dem Grund musst Du Dir den Lambda auch als delegate merken, um ihn dann wieder abmelden zu können.
EventHandler handler = (s,e) => this.myIsDlgActive = false;
dlg.FormClosed += handler;
dlg.FormClosed -= handler;

Auf jeden Fall in den Coding Guidelines festlegen, dass EventHandler nicht mit Lambdas im Stil eines "connect-and-forget" festgelegt werden dürfen. Das kann schnell zu hässlichen MemoryLeaks führen.

Gruß
Florian
05.08.2011
ffordermaier 8,4k 3 9
4
Hallo,

ergänzend zu ffordermaiers Antwort: anonyme Methoden werden als statische Methode compiliert und somit würde die Referenz bis zum Entladen der AppDoamin (i.d.R. bis zum Ende der Anwendung) gehalten und dann kann das eben zu den Speicher-Leaks führen wenn das Objekt das den Handler erstellt schon vorher freigegeben werden könnte.

@ffordermaier: der Begriff "inlinen" ist etwas ungünstig gewählt, denn darunter versteht man eine Compiler-Optimierung (die in .net der JITer dürchführen kann). Die Entscheidung ob eine Methode geinlined wird od. nicht basiert auf einer Heuristik und nicht zwangsläufig jede anonyme Methode muss geinlined werden. Allerdings wird das von dir gezeigte Bsp. ziemlich sicher geinlined.

mfG Gü
05.08.2011
gfoidl 9,4k 3 5
Mit dem Inlining hast Du natürlich Recht, hätte wohl besser "inline schreiben" sagen sollen.
ffordermaier 05.08.2011
1
Noch ein Nachtrag. Anonyme Methoden werden nur dann als statische Methoden kompiliert, wenn sie über keine Variable schließen (also kein Closure bilden). Closures werden vom Compiler in nicht-statische Klassen transformiert.
ffordermaier 05.08.2011

Stelle deine .net-Frage jetzt!
TOP TECHNOLOGIES CONSULTING GmbH