IT박스

C #에서 이벤트 구독을 지우려면 어떻게해야합니까?

itboxs 2020. 6. 23. 07:58

C #에서 이벤트 구독을 지우려면 어떻게해야합니까?


다음 C # 클래스를 보자.

c1 {
 event EventHandler someEvent;
}

c1someEvent이벤트에 대한 구독이 많고 모두 지우고 싶은 경우이를 달성하는 가장 좋은 방법은 무엇입니까? 또한이 이벤트 구독은 람다 / 익명 대리인 일 수 있습니다.

현재 내 솔루션은 해당 세트 ResetSubscriptions()메소드 를 null 로 추가하는 입니다. 이것이 보이지 않는 결과가 있는지 모르겠습니다.c1someEvent


클래스 내에서 (숨겨진) 변수를 null로 설정할 수 있습니다. null 참조는 효과적으로 빈 호출 목록을 나타내는 일반적인 방법입니다.

클래스 외부에서는이 작업을 수행 할 수 없습니다. 이벤트는 기본적으로 "구독"과 "구독 취소"를 표시합니다.

필드와 같은 이벤트가 실제로 수행하는 작업을 인식하는 것이 좋습니다. 변수 이벤트를 동시에 생성하고 있습니다. 클래스 내에서 변수를 참조하게됩니다. 외부에서는 이벤트를 참조합니다.

자세한 내용은 이벤트 및 대리인에 대한 기사 를 참조하십시오.


'someEvent'를 null로 설정하는 메소드를 c1에 추가하십시오 ...

class c1
{
    event EventHandler someEvent;
    ResetSubscriptions() {someEvent = null;}
}

class c1
{
    event EventHandler someEvent;
    ResetSubscriptions() {someEvent = delegate{};}
}

null보다 delegate {}를 사용하는 것이 좋습니다.


클래스 내에서 이벤트를 null로 설정하면 작동합니다. 클래스를 처리 할 때 항상 이벤트를 null로 설정해야합니다. GC는 이벤트에 문제가 있으며 매달려있는 이벤트가있는 경우 처리 된 클래스를 정리하지 못할 수 있습니다.


모든 구독자를 지우는 가장 좋은 방법은이 기능을 외부에 노출하려는 경우 다른 공용 메소드를 추가하여 someEvent를 null로 설정하는 것입니다. 이것은 보이지 않는 결과가 없습니다. 전제 조건은 키워드 'event'로 SomeEvent를 선언하는 것입니다.

요컨대 책, C # 4.0, 125 페이지를 참조하십시오.

여기서 일부는 Delegate.RemoveAll방법 사용을 제안했습니다 . 사용하면 샘플 코드가 아래 양식을 따를 수 있습니다. 그러나 정말 바보입니다. 함수 SomeEvent=null내부에 있지 ClearSubscribers()않습니까?

   public void ClearSubscribers ()
    {
          SomeEvent = (EventHandler) Delegate.RemoveAll(SomeEvent, SomeEvent);// Then you will find SomeEvent is set to null.
    }

Delegate.Remove 또는 Delegate.RemoveAll 메소드를 사용하여이를 수행 할 수 있습니다.


개념적 확장 된 지루한 의견.

"event"또는 "delegate"대신 "event handler"라는 단어를 사용합니다. 그리고 다른 것들에 "이벤트"라는 단어를 사용했습니다. 일부 프로그래밍 언어 (VB.NET, Object Pascal, Objective-C)에서 "이벤트"는 "메시지"또는 "신호"라고하며 "메시지"키워드 및 특정 설탕 구문이 있습니다.

const
  WM_Paint = 998;  // <-- "question" can be done by several talkers
  WM_Clear = 546;

type
  MyWindowClass = class(Window)
    procedure NotEventHandlerMethod_1;
    procedure NotEventHandlerMethod_17;

    procedure DoPaintEventHandler; message WM_Paint; // <-- "answer" by this listener
    procedure DoClearEventHandler; message WM_Clear;
  end;

또한 "메시지"에 응답하기 위해 "대리인"은 단일 대리인이든 여러 대리인이든 응답합니다.

요약 : "이벤트"는 "질문", "이벤트 핸들러"는 답입니다.


이것은 내 솔루션입니다.

public class Foo : IDisposable
{
    private event EventHandler _statusChanged;
    public event EventHandler StatusChanged
    {
        add
        {
            _statusChanged += value;
        }
        remove
        {
            _statusChanged -= value;
        }
    }

    public void Dispose()
    {
        _statusChanged = null;
    }
}

모든 호출 목록 멤버를 등록 해제 Dispose()하려면 using(new Foo()){/*...*/}패턴 을 호출 하거나 사용해야 합니다.


모든 이벤트를 제거하십시오. 이벤트가 "액션"유형이라고 가정하십시오.

Delegate[] dary = TermCheckScore.GetInvocationList();

if ( dary != null )
{
    foreach ( Delegate del in dary )
    {
        TermCheckScore -= ( Action ) del;
    }
}

참고URL : https://stackoverflow.com/questions/153573/how-can-i-clear-event-subscriptions-in-c