2009-08-27 4 views
10

Vom Designer in VS sagen wir, Sie doppelklicken auf eine Schaltfläche und es generiert diesen Click-Ereignishandler.Muss ich alle Event-Handler abmelden?

der Abonnement-Code ist in der designer.cs.

Ich fragte mich, in der Form muss das Formular MUSS ich die Veranstaltung abmelden?

Auch alle Kontrolle, die in der Form sind wird es entsorgt werden, wenn die Formulare verfügt? es tatsächlich aufrufen, über jede Kontrolle rekursiv zu verfügen?

Antwort

15

Sie müssen das Ereignis auf Dispose nicht abhaken, wenn Sie Ihr eigenes Ereignis verknüpfen.

Sie müssen sich nur darum kümmern, wenn Sie ein Ereignis in ein anderes Objekt einhängen. Der Grund dafür ist, dass Ereignis-Hooks eine Referenz am Abonnenten lebendig halten. Wenn Sie sich nicht abmelden, werden Sie keinen Müll sammeln, solange das Observable noch am Leben ist.

Wenn Sie Ihre eigene Veranstaltung anhängen, haben Sie einen Verweis auf sich selbst, der kreisförmig ist, daher brauchen Sie sich keine Gedanken darüber zu machen.

Ich bin gekommen, um mehr lose gekoppelte Ereignismuster aus diesem Grund zu unterstützen. Dies ist die Nummer 1 bei Speicherlecks in .Net. Ich bevorzuge das Muster Event Aggregator (mit weak events).

+0

Danke für die großartige Erklärung. Es macht durchaus Sinn, sich nicht zu lösen, wenn man sich an etwas anhängt. – pdiddy

1

Solange der Event-Handler-Code ist die Form selbst, dann brauchen Sie sich nicht um die Ereignisse zu stornieren - da es keinen baumelnden Ereignishandler zu den Kontrollen sein würde, wie das Formular selbst zerstört werden würde

2

Bei der Frage "Wird es tatsächlich jede Steuerung rekursiv aufrufen?" Lautet die Antwort ja.

Ein einfacher Test kann durchgeführt werden, indem ein Haltepunkt in die Dispose-Methode eines Steuerelements eingefügt wird.

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 

     this.Controls.Add(new SuperButton()); 
    } 
} 

public class SuperButton : Button 
{ 
    protected override void Dispose(bool disposing) 
    { 
     //Place breakpoint on the line below 
     base.Dispose(disposing); 
    } 
}