2010-01-29 11 views
8

Zum Beispiel habe ich eine Basis Event-Publishing-Methode:.NET: Erzeugt jedes Mal, wenn das Ereignis eine gute Übung auslöst, neue EventArgs?

protected virtual OnSomeEvent(EventArgs e) 
    { 
     var handler = SomeEvent; 
     if (handler != null) 
     { 
      handler(this, e); 
      // handler(this, new EventArgs());// EDIT: Yes it should be 
              // handler(this, e), 
              // ignore this one :D 
     } 
    } 

Für eine abgeleitete Klasse, die OnSomeEvent und wirft ein zusätzliches Ereignis überschreibt, wenn er ausgelöst wird:

protected override OnSomeEvent(EventArgs e) 
    { 
     base.OnSomeEvent(e); 

     if (ExtendedEvent != null) 
     { 
      OnExtendedEvent(e); 
     } 
    } 

    protected void OnExtendedEvent(EventArgs e) 
    { 
     // some stuff done 
     // new information the ExtendedEventArgs object needs 
     // is not available until this point 

     ExtendedEvent(this, new ExtendedEventArgs(someStuff, someOtherStuff)); 
    } 

Und wenn Ableitung geht wie folgt auf Es wird ein neues abgeleitete EventArgs für jede Generation der abgeleiteten Klasse, die es erfordert, erstellt. Es scheint jedoch, dass verschiedene Ableitungen von EventArgs auf dem .NET-Framework nicht veränderbar sind (keine Setter), dies hält ein Objekt davon ab, eine einzige Instanz von EventArgs zu behalten und es so zu modifizieren, wie es geht.

Jedes Mal, wenn ein Ereignis wie dieses ausgelöst wird, wird es Speicher für alle beteiligten EventArgs Objekte neu zuordnen. In einer grafikintensiven Anwendung, bei der ein Ereignis dutzende Male pro Sekunde ausgelöst werden kann (z. B. OnPaint Ereignis auf einem Steuerelement), ist das wirklich eine gute Übung?

Sollte ich einige Änderungen an OnExtendedEvent() vornehmen und ExtendedEventArgs veränderbar machen, damit folgendes möglich ist?

protected ExtendedEventArgs extendedArgs = ExtendedEventArgs.Empty; 
    protected void OnExtendedEvent(EventArgs e) 
    { 
     // some stuff done 
     // new information the ExtendedEventArgs object needs 
     // is not available until this point 

     extendedArgs.someProperty1 = someStuff; 
     extendedArgs.someProperty2 = someOtherStuff; 

     ExtendedEvent(this, extendedArgs); 
    } 

BEARBEITEN: Der Beispielcode behoben, sollte jetzt klarer sein.

+1

Die Ableitung ist kein Problem, die abgeleitete Klasse kann base.OnExtendedEvent nur mit EventArgs.Empty aufrufen. Im Allgemeinen haben Sie keine Angst, kurzlebigen Müll zu erstellen. –

+0

Ich denke du meinst unveränderlich statt veränderbar. Unveränderbar bedeutet, dass Sie es nicht ändern können. – aaronb

Antwort

3

Ich würde jedes Mal ein neues unveränderliches Objekt erstellen, da es Werte in den Ereignisargumenten gibt.

Der Hauptgrund ist, was passiert, wenn ein neues Ereignis erneut ausgelöst wird, während ein vorhandenes Ereignis bearbeitet wird?

Dies wird möglicherweise in Multi-Threaded-Anwendungen passiert, kann aber auch auf einem einzelnen Thread passieren, wie das folgende Beispiel zeigt:

erstes Ereignis wird mit den folgenden Werten gebrannt:

extendedArgs.someProperty1 = "Fire 1"; 
extendedArgs.someProperty2 = "Fire 1 Other Stuff"; 

Dann irgendwie Die erste Ereignisbehandlungsroutine bewirkt, dass das Ereignis erneut mit den folgenden Argumenten ausgelöst wird:

extendedArgs.someProperty1 = "Fire 2"; 
extendedArgs.someProperty2 = "Fire 2 Other Stuff"; 

Alle Ereignisbehandlungsroutinen e für das zweite Ereignis werden verarbeitet, und jetzt sind wir wieder bei der Verarbeitung der restlichen Ereignisbehandlungsroutinen für das erste Ereignis.

Jetzt, da das gleiche Objekt verwendet wird, haben nun alle Event-Handler für das erste Event "Fire 2" als someProperty1, da das zweite Event die Werte überschrieben hat.

Als @nobugz erwähnt haben Sie keine Angst, kurzlebigen Müll zu erstellen.

1

Ich bin etwas verwirrt von Ihrem OnExtendedEvent Code - wollen Sie das Ereignis als SomeEvent redispatch?

Wenn ein Client einen Event-Handler fügt hinzu, sie erwarten, dass sie in der Lage sind, den Event-Handler zu entfernen, während das Event-Handling, wie folgt aus:

someObject.SomeEvent += OnSomeEvent; 
// ... 
private void OnSomeEvent(object sender, EventArgs e) 
{ 
    someObject.SomeEvent -= OnSomeEvent; 
} 

Wenn Sie die Standard-Dispatching Praxis nicht folgen, dieser Code Werfen Sie eine Exception sehr zur Überraschung der Person, die Ihren Code verwendet.

+0

Hallo, tut mir leid, der Code ist verwirrend. Jetzt behoben: D – Dan7

5

Zunächst einmal, warum ein EventArgs Argument zu Ihrer Brennmethode nehmen, wenn Sie es sowieso ignorieren? Das ist die wirkliche Verschwendung, aber der Ressourcenverbrauch ist weniger problematisch als die Lüge, die Ihre Methode ihren Anrufern mitteilt. Übergeben Sie einfach das Argument auf, durch, Ihre Brennverfahren wird wahrscheinlich nicht die EventArgs relevante Informationen zu erstellen zugänglich haben Objekt trotzdem:

protected virtual OnSomeEvent(EventArgs e) 
{ 
    var handler = SomeEvent; 
    if (handler != null) 
    { 
     handler(this, e); 
    } 
} 

So, jetzt, dass wir, dass gerade, wenn Ihr EventArgs-Objekt keine sinnvolle Information zu erzählen hat Ihre Abonnenten, verwenden Sie einfach EventArgs.Empty, dafür ist es da. Sie könnten dasselbe Muster für Ihre benutzerdefinierten EventArgs-Klassen verwenden, aber ehrlich gesagt, Sie sorgen sich um nichts. Das Erstellen von EventArgs-Objekten wird nie zu einem Engpass in Ihrer Anwendung führen. Ist dies der Fall, haben Sie Probleme mit dem Entwurf.

Verwandte Themen