2012-01-04 7 views
1

기본적으로 응용 프로그램 Win-Form을 만들 때 양식을 처리하기 위해 Visual Studio에서 생성 한 코드입니다.WinForms 및 이벤트 처리기

protected override void Dispose(bool disposing) 
    { 
     if (disposing && (components != null)) 
     { 
      components.Dispose(); 
     } 
     base.Dispose(disposing); 
    } 

충분하지 않습니까? 또는 가비지 수집기에서 컨트롤을 수집 할 준비가 될 수 있도록 모든 이벤트를 등록 취소해야합니까? 이 종종 close and open 작업에 대상이되는 형태이며, 그 안에 사건의 엄청난 금액을 사용하는 경우

 if (disposing && (components != null)) 
     { 
      myButton.OnClick-= MyFunction; //may be here!! 
      // ... all events used 
      components.Dispose(); 

     } 

답변

0

아니요, 가비지 수집기가 처리합니다. 폼 인스턴스가 삭제 된 이후에 버튼을 배치 한 이후로 이벤트를 더 이상 발생시킬 수 없습니다. 이벤트 처리기로 인해 양식과 버튼 사이에 순환 참조가 있지만 가비지 수집기는 문제가 없습니다.

+0

모든 이벤트를 등록 취소 할 책임이 없다는 뜻입니까? –

+1

@ 한스 패 탄트 (Hans Passant) : 내 경험에 비추어 볼 때, 양식에 영향을 미치는 * 이벤트의 양이 너무 많거나 너무 자주 사용되어 '구독 취소'를하지 않으면 메모리 누수가 발생합니다. – Tigran

+1

예, 그것이 그것이 의미하는 것입니다. 이벤트 소스가 이벤트 고객보다 오래 지속되는 경우에만 필요합니다. 양식과 그 자식 컨트롤에 문제가 없어서 동시에 모두 죽습니다. SystemEvents 클래스의 이벤트는 수동으로 구독을 취소해야하는 이벤트의 예입니다. –

0

, 그것은 모든 이벤트 등록을 취소 중요한입니다. Cuase 이벤트는 자원을 확실히 소모합니다.

이 yuor 응용 프로그램의 MainForm,이 사건에서 탈퇴 중요하지 입니다, 그들에게 잠시 나타납니다, 심지어 지금까지 나타나지 않을 수도 있고,의 말을하자 한 형태 인 경우.

무엇에 대한

그렇게, 나는 개인적으로, 내부 탈퇴,의는 Closing 재정 및 하지Dispose()의를 내부 생각한 것 place.

+0

왜 '배출'하지 않습니까? 클래스에서 IDisposable을 구현할 때 인스턴스에서 'Dispose'를 호출하면 다른 엔터티가 나쁜 상태로 남지 않게됩니다. 이벤트 게시자의 경우, 포기되었지만 결코 구독을 취소하지 않는 구독자의 존재는 나쁜 상태입니다. 즉, 'IDisposable.Dispose'가 방지해야하는 상태입니다. – supercat

+0

@supercat : 가능한 한 빨리 제거하고 사용자가 명시 적으로 호출하지 않았거나 코드 생성 ('using' 문)으로 GC 호출을 기다리지 마십시오. 'Dispose()'를 사용하는 것은 유효한 해결책입니다. btw, 필자는 받아 들일 수없는 것처럼 그것을 거절하지 않았습니다. 단지 주제에 대한 제 의견을주었습니다. – Tigran

+0

'Dispose'가 호출되기 전에 이벤트 연결을 끊지 말아야 함을 의미하는 것이 아니라 'Dispose'가 호출되기 전에 이벤트가 처리되지 않은 경우 'Dispose'가 이벤트를 종료해야한다는 의미입니다. Finalize()는 일반적으로 이벤트 정리에 쓸모가 없습니다. 이벤트를 게시하는 객체가 포기되어 구독을 무의미하게 할 때까지 호출되지 않으며, 한 객체의 Finalize()가 다른 객체 이벤트 연결이 끊어져 야하며, 이벤트 구독 취소는 스레드 안전성이 보장되지 않습니다. – supercat

2

양식은 양식보다 수명이 긴 항목의 모든 이벤트를 등록 해제해야합니다. 양식이 양식과 수명이 동일한 항목의 이벤트 등록을 취소해도 문제가되지 않습니다. 어떤 이유로 든 정상적인 교리는 "문제가 될 때를 제외하고는 등록을 취소하는 것에 대해 걱정하지 마십시오"라고 생각됩니다. 나는 이벤트를 구독하는 모든 객체가 Dispose에 등록되지 않도록하는 것이 훨씬 더 깔끔할 것이라고 생각하지만, 불행하게도 vb.net이나 C#은이를 달성하기 위해 심지어 원격으로 깨끗한 방법을 제공하지 못합니다. IDisposable을 구현하는 종속성을 사용하면 새로 정리 된 항목을 나중에 정리할 항목 목록에 추가하는 루틴으로 구조를 래핑 할 수 있습니다. 그러면 목록의 모든 항목에 대해 Dispose을 호출하여 필요한 모든 정리 작업을 수행 할 수 있습니다. 안타깝게도 .net의 관점에서 보았을 때 동시에 이벤트에 가입하고 동시에 Action<>, IDisposable 또는 구독 취소에 사용될 수있는 다른 객체를 반환하는 범용 루틴을 작성하는 좋은 방법은 없습니다.