2010-06-09 8 views
12

Wenn Sie ein Ereignis in .NET abonnieren, wird das Abonnement einem Multicast-Delegaten hinzugefügt. Wenn das Ereignis ausgelöst wird, werden die Delegierten in der Reihenfolge aufgerufen, in der sie abonniert wurden.Kann ich die Reihenfolge eines Multicast-Delegate-Events umkehren?

Ich möchte das Abonnement irgendwie überschreiben, so dass die Abonnements tatsächlich in der umgekehrten Reihenfolge ausgelöst werden. Kann das gemacht werden und wie?

Ich denke, so etwas wie dies sein könnte, was ich brauche ?:

public event MyReversedEvent 
{ 
    add { /* magic! */ } 
    remove { /* magic! */ } 
} 
+2

Ich dachte, die Reihenfolge, in der die Abonnements gefeuert wurden, war unbestimmt. – ChrisF

+0

@ChrisF: Von MSDN ... "Ein MulticastDelegate hat eine verknüpfte Liste von Delegaten, eine so genannte Aufrufliste, die aus einem oder mehreren Elementen besteht. Wenn ein Multicast-Delegat aufgerufen wird, werden die Delegaten in der Aufrufliste synchron in der Reihenfolge aufgerufen in dem sie erscheinen. " –

+0

@Robert - Ah, ich habe die ** Multicast ** - Bit - Zeit klar beschönigt, um aufzuhören, nach Antworten zu suchen und ins Bett zu gehen. – ChrisF

Antwort

5

Controlling When and If a Delegate Fires Within a Multicast Delegate

Das folgende Verfahren erstellt eine Multicastdelegat allInstances genannt und verwendet dann GetInvocationList jeder Delegierte zu ermöglichen einzeln abgefeuert werden, in umgekehrter Reihenfolge:

public static void InvokeInReverse() 
{ 
    MyDelegate myDelegateInstance1 = new MyDelegate(TestInvoke.Method1); 
    MyDelegate myDelegateInstance2 = new MyDelegate(TestInvoke.Method2); 
    MyDelegate myDelegateInstance3 = new MyDelegate(TestInvoke.Method3); 

    MyDelegate allInstances = 
      myDelegateInstance1 + 
      myDelegateInstance2 + 
      myDelegateInstance3; 

    Console.WriteLine("Fire delegates in reverse"); 
    Delegate[] delegateList = allInstances.GetInvocationList(); 
    for (int counter = delegateList.Length - 1; counter >= 0; counter--) 
    { 
     ((MyDelegate)delegateList[counter])(); 
    } 
} 
+0

Danke - Ich habe es selbst versucht, kurz bevor du deine Antwort gepostet hast und es funktioniert hat - gut, Bestätigung zu sehen, dass ich das Richtige getan habe. :) –

5

Eine Möglichkeit wäre, dies zu handhaben, wenn Sie das Ereignis auslösen. Sie können die Ereignisabonnenten über Delegate.GetInvocationList abrufen und rufen Sie jeden Delegierten in umgekehrter Reihenfolge selbst auf.

+0

Danke - Ich habe es selbst versucht, kurz bevor du deine Antwort geschrieben hast und es funktioniert hat - gut, um die Bestätigung zu sehen, dass ich das Richtige getan habe. :) –

+0

@SLaks: Interessant. Danke - habe die Delegierten-Operatoren nicht auf diese Weise benutzt, bevor ... –

19

Sie brauchen nicht jede Magie; Sie müssen nur die Addition umkehren.
Schreiben delegate1 + delegate2 gibt einen neuen Delegaten zurück, der die Methode (n) in delegate1 enthält, gefolgt von den Methoden in delegate2.

Zum Beispiel:

private EventHandler myReversedEventField; 
public event EventHandler MyReversedEvent 
{ 
    add { myReversedEventField = value + myReversedEventField; } 
    remove { myReversedEventField -= value; } 
} 

Sie brauchen keine Magie in der remove Handler, wenn Sie das letzte Auftreten dieses Handler anstelle des ersten entfernen möchten. (Wenn derselbe Handler zweimal hinzugefügt wurde)

+0

Können Sie bitte Ihre Antwort etwas erweitern? Es wäre gut, den Zusammenhang mit dem von Ihnen geposteten Code zu sehen, damit ich sehen kann, wo ich ihn hinstellen sollte. –

+0

danke für das Update auf deine Antwort. –

+0

@ Neil, Einige Hintergrundinformationen hier: http://www.gavaghan.org/blog/2007/07/25/intercepting-add-and-remove-of-c-event-delegates/ –

Verwandte Themen