Programing

이벤트 핸들러 실행 순서

lottogame 2020. 9. 20. 10:29
반응형

이벤트 핸들러 실행 순서


다음과 같이 여러 이벤트 핸들러를 설정하면 :

_webservice.RetrieveDataCompleted += ProcessData1;
_webservice.RetrieveDataCompleted += ProcessData2;

이벤트 RetrieveDataCompleted시작될 때 핸들러는 어떤 순서로 실행 됩니까? 동일한 스레드에서 등록 된 순서대로 순차적으로 실행됩니까?


현재 등록 된 순서대로 실행됩니다. 그러나 이것은 구현 세부 사항이며 사양에 필요하지 않기 때문에 향후 버전에서 동일하게 유지되는이 동작에 의존하지 않을 것입니다.


대리자의 호출 목록은 목록의 각 요소가 대리자가 호출 한 메서드 중 정확히 하나를 호출하는 순서가 지정된 대리자 집합입니다. 호출 목록에는 중복 메소드가 포함될 수 있습니다. 호출 중에 델리게이트는 호출 목록에 나타나는 순서대로 메서드를 호출합니다 .

여기에서 : Delegate Class


모든 핸들러를 분리 한 다음 원하는 순서로 다시 연결하여 순서를 변경할 수 있습니다.

public event EventHandler event1;

public void ChangeHandlersOrdering()
{
    if (event1 != null)
    {
        List<EventHandler> invocationList = event1.GetInvocationList()
                                                  .OfType<EventHandler>()
                                                  .ToList();

        foreach (var handler in invocationList)
        {
            event1 -= handler;
        }

        //Change ordering now, for example in reverese order as follows
        for (int i = invocationList.Count - 1; i >= 0; i--)
        {
            event1 += invocationList[i];
        }
    }
}

등록 된 순서대로 실행됩니다. RetrieveDataCompletedA는 멀티 캐스트 대표 . 나는 반사경을 통해 확인하고 시도하고 있으며 모든 것을 추적하기 위해 배후에서 배열이 사용되는 것처럼 보입니다.


순서는 임의적입니다. 한 호출에서 다음 호출까지 특정 순서로 실행되는 핸들러에 의존 할 수 없습니다.

편집 : 또한-이것이 단지 호기심에서 나온 것이 아니라면-알아야 할 사실은 심각한 디자인 문제를 나타냅니다 .


누군가 System.Windows.Forms.Form의 컨텍스트에서이 작업을 수행해야하는 경우 다음은 Shown 이벤트의 순서를 반전하는 예제입니다.

using System;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;

namespace ConsoleApplication {
    class Program {
        static void Main() {
            Form form;

            form = createForm();
            form.ShowDialog();

            form = createForm();
            invertShownOrder(form);
            form.ShowDialog();
        }

        static Form createForm() {
            var form = new Form();
            form.Shown += (sender, args) => { Console.WriteLine("form_Shown1"); };
            form.Shown += (sender, args) => { Console.WriteLine("form_Shown2"); };
            return form;
        }

        static void invertShownOrder(Form form) {
            var events = typeof(Form)
                .GetProperty("Events", BindingFlags.Instance | BindingFlags.NonPublic)
                .GetValue(form, null) as EventHandlerList;

            var shownEventKey = typeof(Form)
                .GetField("EVENT_SHOWN", BindingFlags.NonPublic | BindingFlags.Static)
                .GetValue(form);

            var shownEventHandler = events[shownEventKey] as EventHandler;

            if (shownEventHandler != null) {
                var invocationList = shownEventHandler
                    .GetInvocationList()
                    .OfType<EventHandler>()
                    .ToList();

                foreach (var handler in invocationList) {
                    events.RemoveHandler(shownEventKey, handler);
                }

                for (int i = invocationList.Count - 1; i >= 0; i--) {
                    events.AddHandler(shownEventKey, invocationList[i]);
                }
            }
        }
    }
}

A MulticastDelegate has a linked list of delegates, called an invocation list, consisting of one or more elements. When a multicast delegate is invoked, the delegates in the invocation list are called synchronously in the order in which they appear. If an error occurs during execution of the list then an exception is thrown.


During an invocation, methods are invoked in the order in which they appear in the invocation list.

But nobody says that invocation list maintain delegates in the same order as they are added. Thus invocation order is not guaranteed.

참고URL : https://stackoverflow.com/questions/1645478/order-of-event-handler-execution

반응형