2008-10-09 6 views
28

WeakReference를 통해 이벤트 처리를 구현하는 것이 좋습니다. 해당 이벤트가 참조를 보유하고있는 유일한 경우이며 가비지 수집 대상이 필요합니다. 이 인수로Weak 참조 및 이벤트 처리

:

밥상은 당신이 뭔가에 가입하는 경우는 취소하는 것은 사용자의 책임이다라고 당신이 그것을해야한다.

+0

질문은 다음과 같습니다. 개체가 가비지 수집 될 때까지 해당 이벤트가 시작될 가능성은 무엇입니까? 왜 WeakReference를 처음 사용합니까? –

+0

@Jon Limjap은 약한 참조없이 이벤트가 오브젝트의 트랙을 유지하므로 수집되지 않기 때문에 기회가 0이 아닙니까? – fostandy

+0

@fostandy : 아니요, 이벤트 게시자는 구독자가 보관하지 않으며 다른 방법으로 만 작동합니다. 가입자가 먼저 구독을 취소하지 않고 GC'ed 될 수 있도록하려면 WeakReference를 사용해야합니다. 참조 : http://stackoverflow.com/a/298276/134761 – angularsen

답변

-2

당신이 제안하는 것이 문제 (이벤트 참조 관리 및 메모리 누출 방지)의 한 세트를 해결하지만 새로운 문제를 야기 할 수 있습니다.

원본 개체가 가비지 수집 된 경우 (약한 참조로만 유지됨) 이벤트가 처리되는 동안 볼 수있는 한 가지 문제는 원본 개체에 액세스하는 모든 코드가 Null 참조 예외가 발생한다는 것입니다. 이벤트 핸들러는 소스 객체에 액세스하지 않거나 강력한 참조를 가져야한다고 주장 할 수 있지만, 이것이 처음에 해결하려고하는 것보다 더 심각한 문제 일 수 있다고 주장 할 수 있습니다.

+1

CLR이 이미 이벤트 핸들러를 실행하면 스택은 "this"에 대한 참조를 보유하며 오브젝트는 수집되지 않습니다. –

9

약한 대리자 패턴은 CLR에 있어야합니다. 정상적인 이벤트는 "살아있을 때 알려줍니다"의미를 나타내지 만 "살아있을 때 알림"이 필요한 경우가 많습니다. WeakReference에 대한 위임을하는 것은 잘못된 것입니다. 왜냐하면 위임은 객체이기도하고, 수신자가 아직 살아 있고 수신 참조가있을 때조차도, 위임 자체는 위크 참조에 의해 참조되고 즉시 수집됩니다. 구현 예는 this old post을 참조하십시오.

6

대리인이 참조를 보유하고 있기 때문에 약한 참조 자체는 문제를 해결하지 못합니다. Prism (www.microsoft.com/compositewpf)과 함께 제공되는 복합 응용 프로그램 라이브러리에는 소스에서 가져올 수있는 WeakDelegate 클래스가 있습니다. WeakDelegate는 기본적으로 리플렉션을 실행하고 잠시 동안 만 델리게이트를 만든 다음 해제하여 아무 포인터도 유지하지 않습니다. CAL 내에서는 EventAggregator 클래스에 의해 사용되지만 MS-PL에서와 마찬가지로 자체 용도로 자유롭게 추출 할 수 있습니다.

13

할 수있을 때 이벤트 구독을 취소하는 습관을 가지는 것이 좋지만 때로는 할 수있는 명백한 "정리"방법이 없습니다. 최근에이 주제에 blog article을 게시했습니다. WeakReference를 사용하여 이벤트에 쉽게 가입 할 수있는 메소드가 포함되어 있습니다.