2010-06-09 13 views
12

Po zasubskrybowaniu zdarzenia w .NET subskrypcja jest dodawana do delegata multiemisji. Po wystrzeleniu zdarzenia delegaci są wywoływani w kolejności, w której zostali zasubskrybowani.Czy mogę odwrócić kolejność zdarzeń delegowania multiemisji?

Chciałbym jakoś przesłonić subskrypcję, aby subskrypcje zostały faktycznie wysłane w kolejności odwrotnej. Czy można to zrobić i jak?

Myślę, że coś takiego może być to, czego potrzebuję ?:

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

Myślałem, że zamówienie, w którym subskrypcje zostały zwolnione, było nieokreślone. – ChrisF

+0

@ChrisF: Od MSDN ... "MulticastDelegate ma połączoną listę delegatów, nazywaną listą wywołań, składającą się z jednego lub więcej elementów. Gdy delegat multiemisji jest wywoływany, delegatów na liście wywołań nazywa się synchronicznie w kolejności w którym się pojawiają. " –

+0

@Robert - Ah, wyraźnie pomalowałem na ** multicast ** bit - czas przestać szukać pytań do odpowiedzi i iść spać. – ChrisF

Odpowiedz

5

Controlling When and If a Delegate Fires Within a Multicast Delegate

Poniższa metoda tworzy multicast delegata nazwie allinstances a następnie używa GetInvocationList by każdy delegat zostać zwolniony indywidualnie, w odwrotnej kolejności:

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

Dzięki - spróbowałem tego sam przed opublikowaniem odpowiedzi i działałem dobrze - widzę potwierdzenie, że postąpiłem słusznie. :) –

5

Jedną z opcji byłoby obsługiwać to kiedy podnieść zdarzenie. Możesz uzyskać subskrybentów zdarzeń przez Delegate.GetInvocationList i po prostu wywołaj każdego delegata w odwrotnej kolejności.

+0

Dzięki - próbowałem tego sam, zanim opublikowałeś swoją odpowiedź i działało - dobrze, aby zobaczyć potwierdzenie, że postąpiłem słusznie. :) –

+0

@SLaks: Interesujące. Dzięki - nie wykorzystałem w ten sposób operatorów delegatów przed ... –

19

Nie trzeba jakakolwiek magia; po prostu trzeba odwrócić dodawanie.
Pisanie delegate1 + delegate2 zwraca nowego delegata zawierającego metody w delegate1, a następnie metody w delegate2.

Na przykład:

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

Nie trzeba żadnej magii w przewodnika remove, chyba, że ​​chcesz usunąć ostatnie wystąpienie tego przewodnika zamiast pierwszego. (W przypadku, gdy ten sam handler został dodany dwukrotnie)

+0

Czy możesz nieco rozwinąć swoją odpowiedź, proszę? Dobrze byłoby zobaczyć kontekst związany z opublikowanym przez ciebie kodem, dzięki czemu mogę zobaczyć, gdzie powinienem go umieścić. –

+0

dzięki za aktualizację odpowiedzi. –

+0

@Neil, Niektóre podstawowe informacje tutaj: http://www.gavaghan.org/blog/2007/07/25/intercepting-add-and-remove-of-c-event-delegates/ –

Powiązane problemy