2017-01-01 6 views
3

Ich möchte ein Ereignis auslösen und bestehende Abonnenten informieren, wenn solche existieren. Aber ich erwarte auch, dass neue Abonnenten von allen Veranstaltungen benachrichtigt werden, sobald sie sich angemeldet haben. Ist das out-of-the-box möglich oder muss ich diese Funktionalität selbst implementieren? Gerade jetzt mein Code wie folgt aussehen:Raise ein Ereignis, bevor jemand es abonniert hat

public delegate void GridCompiled(int gridsize); 
public event GridCompiled OnGridCompiled; 

ctor(){ 
    if (OnGridCompiled != null) 
     OnGridCompiled(gridsize); 
} 

Wenn Veranstaltung 0 Abonnenten hat, wird es nicht angehoben werden, und es wird auch nicht für Abonnenten erhöht werden, die nach dem Ereignis zu abonnieren angehoben worden.

Falls ich das selbst implementieren muss, welche Optionen habe ich?

+0

könnte ein viel des Guten, aber Rx.Net ist ein 'Replay' Methode bietet: http://www.introtorx.com/Content/v1.0.10621.0/14_HotAndColdObservables.html#Replay – haim770

+5

scheint mir, wie Sie suchen nach einer Nachrichtenwarteschlange, nicht nach Ereignissen. –

Antwort

5

Es gibt keine Verfolgung von Ereignissen, die ausgelöst werden müssen. Sie müssen die Funktionalität also selbst implementieren. Sie würden eine Liste benötigen eine Vorveranstaltung Argumente, um zu speichern und die damit verbundenen Ereignisse ausgeführt werden, wenn ein neues Ereignis-Listener hinzugefügt:

class Example { 
    private readonly List<GridCompiledEventArgs> m_previousEventArgs = new List<EventArgs>(); 
    private EventHandler<GridCompiledEventArgs> m_gridCompiled; 

    public event EventHandler<GridCompiledEventArgs> GridCompiled { 
     add { 
      //Raise previous events for the caller 
      foreach(GridCompiledEventArgs e in m_previousEventArgs) { 
       value(this, e); 
      } 
      //Add the event handler 
      m_gridCompiled += value; 
     } 
     remove { 
      m_gridCompiled -= value; 
     } 
    } 

    protected virtual void OnGridCompiled(GridCompiledEventArgs e) { 
     if (m_gridCompiled != null) { 
      m_gridCompiled(this, e); 
     } 
     m_previousEventArgs.Add(e); 
    } 
} 

Es gibt zwei Dinge, die Sie für diese Lösung betrachten haben. Wenn Sie sie adressieren wollen, werden Ihre Lösung komplexer:

  1. Wenn GridCompiledEventArgs kann durch einen Event-Handler geändert werden (zB einen Status an den Anrufer zurück), werden die Veranstaltung args in der Vorveranstaltung gespeichert Liste mit diesen Änderungen. Wenn ein Ereignishandler einen Verweis auf die Ereignisargumente behält, können sie ihn später sogar ändern. Wenn Sie das nicht möchten, müssen Sie eine Kopie in m_previousEventArgs speichern und eine weitere Kopie erstellen, bevor Sie das Ereignis "historic" auslösen.
  2. Es wird empfohlen, dass abgeleitete Klassen die OnGridCompiled-Methode überschreiben, anstatt das Ereignis zu behandeln oder das Verhalten zu ändern. Wenn eine abgeleitete Klasse OnGridCompiled ändert, um das Ereignis abzufangen und in bestimmten Fällen nicht zu erhöhen, wird dieses Verhalten nicht immer für das Ereignis "historic" gelten, da es ohne OnGridCompiled ausgelöst wird (was möglicherweise das gewünschte Verhalten ist). Wenn Sie das ändern möchten, müssen Sie eine Lösung implementieren, die OnGridCompiled durchläuft. Wenn dies eine Option für Sie ist, können Sie dieses Problem vermeiden, indem Sie die Klasse sealed und die OnGridCompiled Methode private anstelle von protected virtual.
+0

Danke. Punkt 2 gilt nicht für meinen Fall, da die Klasse bereits versiegelt ist, aber ich muss Punkt 1 berücksichtigen. Ich habe jedoch noch eine weitere Frage. Warum hast du nicht 'private event EventHandler m_gridCompiled;'? –

+1

Weil es kein Event ist. 'GridCompiled' ist das Ereignis. 'm_gridCompiled' ist nur das Backer-Feld, das den Event-Handler speichert. Das gesamte Konstrukt heißt _event method syntax_. – Sefe

+0

Vielleicht sollte ich auf meine Frage eingehen. Ich verstehe Ereignis als eine Liste von Methoden, die aufgerufen werden, wenn Sie das Ereignis auslösen, und ich dachte, Schlüsselwort 'Ereignis' ist für dieses Verhalten wesentlich. Aber im obigen Beispiel können Sie den Event-Handler zu "m_gridCompiled" hinzufügen (was kein Event ist) und ihn genauso auslösen, wie Sie ein Event auslösen würden. Gibt es Keyword 'Event' nur für Code-Klarheit? –

Verwandte Themen