programing

이벤트 핸들러가 이미 추가되었습니까?

lovejava 2023. 4. 29. 08:09

이벤트 핸들러가 이미 추가되었습니까?

이벤트 핸들러가 개체에 추가되었는지 확인할 수 있는 방법이 있습니까?SQL 기반 세션 상태를 사용할 수 있도록 세션 상태에 개체 목록을 직렬화하는 중입니다.목록의 개체에 속성이 변경된 경우 플래그를 지정해야 합니다. 이 플래그는 이벤트 처리기에서 이전에 제대로 처리했습니다.그러나 이제 객체가 역직렬화되면 이벤트 핸들러를 가져오지 않습니다.

약간 짜증이 나서 개체에 액세스하는 Get 속성에 이벤트 핸들러를 추가했습니다.지금 호출되고 있는데, 5번 정도 호출된다는 점을 제외하고는 훌륭해서 객체에 액세스할 때마다 핸들러가 계속 추가되는 것 같습니다.

그냥 무시해도 될 정도로 정말 안전하지만, 핸들러가 이미 추가되었는지 확인하여 한 번만 더 깨끗하게 만들고 싶습니다.

그게 가능한가요?

편집: 추가되는 이벤트 핸들러를 완전히 제어할 수 있는 것은 아니므로 null을 확인하는 것만으로는 충분하지 않습니다.

저는 최근에 이벤트에 핸들러를 한 번만 등록해야 하는 비슷한 상황에 처했습니다.핸들러가 전혀 등록되지 않았더라도 먼저 안전하게 등록을 취소한 다음 다시 등록할 수 있습니다.

myClass.MyEvent -= MyHandler;
myClass.MyEvent += MyHandler;

핸들러를 등록할 때마다 이 작업을 수행하면 핸들러가 한 번만 등록됩니다.나에게는 꽤 좋은 연습처럼 들립니다 :)

@Telos가 언급한 것처럼 정의 클래스 외부에서는 EventHandler를 왼쪽에서만 사용할 수 있습니다.+= 는또.-=클래스를 수 있는 가 "" "" "" "" "" "" 수할 수 있습니다.null이 경우 이벤트 핸들러가 추가되지 않았습니다.그렇지 않은 경우에는 대리자의 값을 반복 표시할 수 있습니다.호출 목록을 가져옵니다.이벤트 핸들러로 추가할 대리자와 동일한 대리자가 있으면 해당 대리자가 존재한다는 것을 알 수 있습니다.

public bool IsEventHandlerRegistered(Delegate prospectiveHandler)
{   
    if ( this.EventHandler != null )
    {
        foreach ( Delegate existingHandler in this.EventHandler.GetInvocationList() )
        {
            if ( existingHandler == prospectiveHandler )
            {
                return true;
            }
        }
    }
    return false;
}

그리고 이것은 "핸들러가 없으면 핸들러 추가"가 되도록 쉽게 수정될 수 있습니다.이벤트를 노출하고 있는 클래스의 내부에 액세스할 수 없는 경우 탐색이 필요할 수 있습니다.-=그리고.+=@Lou Franco가 제안한 바와 같이.

그러나 이러한 개체를 커미셔닝하고 해제하는 방법을 다시 검토하여 이 정보를 직접 추적할 수 있는지 확인하는 것이 좋습니다.

이 처리기가 유일한 처리기인 경우 이벤트가 null인지 확인할 수 있습니다. 그렇지 않은 경우 처리기가 추가되었습니다.

추가되지 않았더라도(그렇지 않을 경우 잡을 수 있었다) 핸들러와 함께 이벤트에서 -=를 안전하게 호출하여 추가하기 전에 해당 이벤트에 없는지 확인할 수 있다고 생각합니다.

다음 예제에서는 GetInvocationList() 메서드를 사용하여 추가된 모든 처리기에 대한 위임을 검색하는 방법을 보여 줍니다.특정 핸들러(함수)가 추가되었는지 확인하려는 경우 배열을 사용할 수 있습니다.

public class MyClass
{
  event Action MyEvent;
}

...

MyClass myClass = new MyClass();
myClass.MyEvent += SomeFunction;

...

Action[] handlers = myClass.MyEvent.GetInvocationList(); //this will be an array of 1 in this example

Console.WriteLine(handlers[0].Method.Name);//prints the name of the method

대리자의 메서드 속성에서 다양한 속성을 검사하여 특정 함수가 추가되었는지 확인할 수 있습니다.

하나만 연결되어 있는지 확인하려는 경우에는 null을 테스트하면 됩니다.

이벤트를 추가할 때 true로 설정한 부울 변수를 만드는 방법밖에 없었습니다.그런 다음 질문합니다. 변수가 거짓이면 이벤트를 추가합니다.

bool alreadyAdded = false;

이 변수는 전역 변수일 수 있습니다.

if(!alreadyAdded)
{
    myClass.MyEvent += MyHandler;
    alreadyAdded = true;
}

제가 당신의 문제를 올바르게 이해한다면 당신은 더 큰 문제가 있을 수 있습니다.다른 개체가 이러한 이벤트를 구독할 수 있다고 말씀하셨습니다.개체가 직렬화 및 역직렬화되면 다른 개체(제어할 수 없는 개체)의 이벤트 핸들러가 손실됩니다.

만약 당신이 그것에 대해 걱정하지 않는다면, 당신의 이벤트 핸들러에 대한 참조를 유지하는 것이 충분할 것입니다.다른 개체의 이벤트 핸들러가 손실되는 부작용이 걱정되는 경우 캐싱 전략을 재고해 보는 것이 좋습니다.

나는 알프의 대답에 동의하지만, 그것에 대한 약간의 수정은, 사용하는 것입니다.

           try
            {
                control_name.Click -= event_Click;
                main_browser.Document.Click += Document_Click;
            }
            catch(Exception exce)
            {
                main_browser.Document.Click += Document_Click;
            }
EventHandler.GetInvocationList().Length > 0

언급URL : https://stackoverflow.com/questions/136975/has-an-event-handler-already-been-added