나는 그 패턴이 당신이 기대하는대로하지 않는다고 생각합니다. 메모리 누수를 방지하기 위해 이벤트가 현재 객체에 대한 참조를 보유하지 못하도록하려고합니까? 람다 식은 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);
처리기를 수집 한 후 이벤트에서 처리해야하므로 이벤트가 정기적으로 발생하는 한 메모리 누수를 방지해야합니다.
내 질문/답변 [여기] (http://stackoverflow.com/questions/1747235/weak-event-handler-model-for-use-with-lambdas)를 보았습니까? 그것은 하나의 라이너는 아니지만, 나는 생각합니다. * 작동합니다 ... – Benjol