2010-05-27 3 views
9

저는 최근에 메모리 관리에 대해 많은 조사를 해왔고 이벤트 관리 방법을 살펴 보았습니다. 이제는 이벤트 구독에 대한 명시 적 추가/제거 구문을보고 있습니다.명시 적 이벤트 추가/제거, 오해?

매우 간단하고 추가/제거 만하면 가입 및 탈퇴 할 때 다른 논리를 수행 할 수 있다고 생각하십니까? 나는 그것을 얻고 있는가, 아니면 더 많이 가지고 있는가?

또한 여기에있는 동안 내 이벤트 정리를위한 조언/모범 사례가 처리됩니다.

답변

3

구문 추가/제거는 일반적으로 이벤트 구현을 다른 클래스로 "전달"하는 데 사용됩니다.

IDisposable을 구현하면 가입 (이벤트 핸들 아님)을 정리하는 것이 가장 좋습니다.

업데이트 : 어떤 개체가 IDisposable을 구현해야하는지에 따라 약간의 차이가 있습니다. Rx 팀은 설계 관점에서 최상의 결정을 내 렸습니다. 구독 자체는 IDisposable입니다. 정규 .NET 이벤트에는 구독을 나타내는 개체가 없으므로 게시자 (이벤트가 정의 된 클래스)와 구독자 (대개 구독중인 멤버 함수가 들어있는 클래스) 사이에서 선택됩니다. 필자의 디자인 본능이 구독자 IDisposable을 선호하지만 대부분의 실제 코드는 게시자를 IDisposable으로 만듭니다. 구현이 쉽고 실제 구독자 인스턴스가없는 경우가있을 수 있습니다.

은 (코드 실제로 모든 이벤트 구독을 정리하는 경우 즉,이다. 대부분의 코드는하지 않습니다.)

+0

하하, 나는 동료들과 이야기 할 때 구독으로 언급하지만 질문을 올리는 순간 나는 잘못된 용어를 사용하고 있습니다. 설명해 주셔서 감사합니다. – Hammerstein

6

예, 추가/구문을 제거 당신이 당신의 자신의 가입 로직을 구현 할 수 있습니다. 이벤트를위한 표준 표기법을 제외하면 컴파일러는 표준 구현을 생성합니다. 자동 속성과 같습니다.

다음 샘플에서는 Event1과 Event2 사이에 실제 차이점이 없습니다.

public class Foo 
{ 
    private EventHandler handler; 
    public event EventHandler Event1 
    { 
    add { handler += value; } 
    remove { handler -= value; } 
    } 

    public event EventHandler Event2; 
} 

그러나 이것은 '정리'처리기와는 별개의 주제입니다. 그것은 구독 취소를해야하는 구독 클래스입니다. 출판 학급은 이걸별로 도와 줄 수 없습니다.
이벤트의 가입 목록을 '정리'하는 클래스를 상상해보십시오. Disposed 클래스는 대개 Disposed 직후에 수집 가능하기 때문에 이것은 자체적으로 Disposed 될 때만 현명하게이를 수행 할 수 있으며 생산적이지는 않습니다.

+1

나는 최종 사용자가 할 수 없다고 믿는다 :'Foo foo = ...; foo.Event1 (보낸 사람, 전자),'할 수 있지만'foo.Event2 (null, null);'할 수 있습니다. – user7116

+0

예제와 설명을 해주셔서 감사합니다. 나는 그것이 있다고 생각했다. 그러나 나는 그것을 생각하고 있었다! 메모리 관리에 대한 질문을 별도의 질문으로 게시하겠습니다. 물어보고 싶은 것이 많습니다. – Hammerstein

+0

두 경우 모두 오류가 발생하지만 두 번째 경우에는 오류가 발생합니다. '오류 CS0070 :'Program.Foo.Event2 '이벤트는 + = 또는의 왼쪽에만 나타날 수 있습니다. - = ('Program.Foo'유형 내에서 사용될 때 제외)'. – user7116

9

추가/제거 속성은 기본적으로 다른 멤버와 함께 설정/가져 오기 속성을 사용하는 것과 같은 논리를 사용합니다. 이벤트 등록시 추가 로직을 작성하고 이벤트 자체를 캡슐화 할 수 있습니다.

당신이 그것을하고 싶은 좋은 예는 필요하지 않을 때 추가 계산을 중지하는 것입니다 (아무도 이벤트를 듣지 않습니다).

예를 들어, 이벤트가 타이머에 의해 트리거되는 말할 수 있습니다, 우리는 아무도 이벤트에 등록되어 있지 않은 경우 타이머가 작동하지 않습니다

private System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer(); 
private EventHandler _explicitEvent; 
public event EventHandler ExplicitEvent 
{ 
    add 
    { 
     if (_explicitEvent == null) timer.Start(); 
     _explicitEvent += value; 
    } 
    remove 
    { 
     _explicitEvent -= value; 
     if (_explicitEvent == null) timer.Stop(); 
    } 
} 

당신은 아마 싶어 (추가 고려 사항) ...

관련 문제