2010-07-15 2 views
8

여러 가지 용도가 DRY 원칙을 위반한다는 사실 외에도이 한쪽 라이너에 대한 단점을 확인할 수 있습니까? 그것은 간단 해 보이지만 다른 사람들이 그것을 제안하지 않는다는 사실은 그것이 나에게 단점이 있는지 궁금하게 만든다.하나의 라이너 : 약한 람다 이벤트 처리기

이 코드는 메서드에 WeakReference을 만든 다음 참조 대상을 호출하는 이벤트 처리기를 등록합니다.

SomeEvent += (sender, e) => ((Action)(new WeakReference((Action)ProcessEvent)).Target)(); 

감사합니다,

+0

내 질문/답변 [여기] (http://stackoverflow.com/questions/1747235/weak-event-handler-model-for-use-with-lambdas)를 보았습니까? 그것은 하나의 라이너는 아니지만, 나는 생각합니다. * 작동합니다 ... – Benjol

답변

11

나는 그 패턴이 당신이 기대하는대로하지 않는다고 생각합니다. 메모리 누수를 방지하기 위해 이벤트가 현재 객체에 대한 참조를 보유하지 못하도록하려고합니까? 람다 식은 ProcessEvent (ProcessEvent은 인스턴스 메서드라고 가정)을 평가하기 위해 this의 값을 캡처하므로 누출이 여전히 있습니다. 이 코드는 SomeEvent += (sender, e) => ProcessEvent();과 동일합니다.

당신은 (또한 당신이 원하는하지 않은) 더 이런 일을하려고 할 수있다 : 당신은 강한 참조가되지 않도록,

var reference = new WeakReference((Action)ProcessEvent); 
SomeEvent += (sender, e) => ((Action)reference.Target)(); 

지금 람다 표현식은 WeakReference를 캡처합니다 this. 불행히도 ProcessEvent에서 만든 대리자를 참조하는 것은 없으므로 this이 아직 살아 있어도 다음 GC에서 제거됩니다. (이것은 Target이 null 인지도 확인하지 않습니다.)

이 같은 시도 할 수 있습니다 : 다음과 같이 사용 후

public EventHandler MakeWeakHandler(Action action, Action<EventHandler> remove) 
{ 
    var reference = new WeakReference(action.Target); 
    var method = action.Method; 
    EventHandler handler = null; 
    handler = delegate(object sender, EventArgs e) 
    { 
     var target = reference.Target; 
     if (target != null) 
     { 
      method.Invoke(target, null); 
     } 
     else 
     { 
      remove(handler); 
     } 
    }; 
    return handler; 
} 

과 :의 processEvent의 수신기에 약한 참조를 유지하며, 자동으로 이벤트를 제거합니다

SomeEvent += MakeWeakHandler(ProcessEvent, h => SomeEvent -= h); 

처리기를 수집 한 후 이벤트에서 처리해야하므로 이벤트가 정기적으로 발생하는 한 메모리 누수를 방지해야합니다.

+0

이것은 어떤 이벤트에도 적용되지 않습니다. 예를 들어 EventArgs를 PropertyChangedEventArgs로 바꾸고 EventHandler를 PropertyChangedEventHandler로 바꾸는 등의 * 정확한 * 이벤트를 전문화해야합니다. 유형을 전달할 수 있지만 작동하지 않는 일반 버전을 빌드하려고했습니다. –

0

그것의 매우 읽을 수 없습니다. 그리고 단계별로 디버깅해야한다면, 그 중 하나라도 실패 할 수는 있지만 그 한 줄은 실패 할 것입니다. 또한 스택 추적에서 참조되는 단일 행만 가져옵니다.

일반적으로 유지 관리를 위해 한 줄에 너무 많은 일을하지 않으려합니다.