2012-04-02 9 views
3

Ich möchte den Event-Handler nur einmal aufrufen und dann trennen. Ich habe versucht zu schreiben:Entfernen eines Handlers beim ersten Aufruf

EventHandler handler = (s, e) => 
{ 
    // Do something 
    // 
    // blabla 

    // Detach the handler 
    SizeChanged -= handler; 
}; 
SizeChanged += handler; 

jedoch auf der SizeChanged -= handler Linie bekomme ich diesen Fehler

Use of unassigned local variable 'handler' 

Haben Sie iDEAD, wie ich vorgehen sollte? Ich habe über die Verwendung eines booleschen Flags nachgedacht, aber ich werde das nur tun, wenn ich keine Möglichkeit finde, den Handler zu lösen.

Antwort

3

Dies ist, weil es wirklich noch nicht zugewiesen ist. Versuchen Sie, eine benannte Methode daraus zu machen, daher ist das Symbol vorhand bekannt.

private void OnEvent(object sender, EventArgs e) 
{ 
    // Do something 

    AnEvent -= OnEvent; 
} 

private void RegisterOnce() 
{ 
    AnEvent += OnEvent; 
} 

Ich würde auch erst nach detatch dem DoSmething Code auszuführen empfehlen und einig Verriegelungsmechanismus zu implementieren, falls Sie multithrading haben, um zu verhindern, mehr Threads das Ereignis an der exakt gleichen Zeit rufen, nicht die Zeit, die detatch und deshalb laufen alle.

6

Der C# -Compiler erstellt zuerst den Lambda-Ausdruck, den Sie geschrieben haben, bevor das Ergebnis der Variablen zugewiesen wird. Wenn also das Lambda definiert ist, hat der Handler keinen Wert.

Es funktioniert jedoch, wenn Sie zuvor EventHandler den Wert null zuweisen.

Da es eine Schließung und lokale Variablen in der Schließung erfasst, die zum Zeitpunkt des Anrufs Handler den richtigen Wert haben und es wird funktionieren:

 EventHandler handler=null; 

     handler = (s, e) => 
     { 
      // Do something 
      SizeChanged -= handler; 
     }; 
     SizeChanged += handler; 

An alle Leute Downvoting: Er gewann verursachen keine NullReferenceException. handler ist eine lokale Variable, die in der Closure erfasst wird. Daher ändert sich der Wert des Handlers innerhalb des Lambda, wenn er in der Methode geändert wird, die die Closure enthält. Ich habe es tatsächlich auf meinem PC getestet und es funktioniert perfekt.

+1

Wenn Sie das tun, haben Sie null Ref-Ausnahme in Ihrem Rückruf ... –

+2

Nein, versuchen Sie es. Der Handler wird in der Schließung erfasst. – aKzenT

+2

Hey, wähle mich nicht ab, bevor du es probiert hast !!! Lesen Sie weiter, wie Schließungen funktionieren ... – aKzenT

Verwandte Themen