사용 할 수있는 람다 식으로 이벤트를 처리기는 메모리 누수가 발생?
-
08-06-2019 - |
문제
말로는 우리가 다음 방법:
private MyObject foo = new MyObject();
// and later in the class
public void PotentialMemoryLeaker(){
int firedCount = 0;
foo.AnEvent += (o,e) => { firedCount++;Console.Write(firedCount);};
foo.MethodThatFiresAnEvent();
}
하드 디스크 드라이브가 이 방법으로는 인스턴스화과 PotentialMemoryLeaker
방법은 여러 번 호출,우리는 메모리 누수가?
방법은 없을 분리하는 람다 이벤트 처리한 후에 우리는 전화 MethodThatFiresAnEvent
?
해결책
예,저장할 변수를 풉니다.
DelegateType evt = (o, e) => { firedCount++; Console.Write(firedCount); };
foo.AnEvent += evt;
foo.MethodThatFiresAnEvent();
foo.AnEvent -= evt;
그리고 예,당신이하지 않는 경우,당신 누출 메모리로,당신은 걸 새로운 대체됩니다.당신은 또한 알 수 있기 때문에 이를 호출할 때마다 이 방법을 덤프하는 콘솔의 증가 수는 라인(다만 늘지만,하나의 전화를 MethodThatFiresAnEvent 그것을 덤프하는 모든 항목의 수를,한 번에 대한 각 매 익명 method).
다른 팁
당신은 늘 단지 메모리 누수,당신은 또한 당신의 람다 여러 번 호출.각 호의'PotentialMemoryLeaker'가의 복사본을 lambda 이벤트 목록,그리고 모든 사본을 것이라고 할 때'AnEvent'가 발생합니다.
라 확장할 수 있습니다 무슨 일이 완료되었습니다 기 을 만드 대리자가 안전하게 사용(어떤 메모리 누수)
귀하의를 컴파일하는 컴파일러 명 개의 내부 클래스(현장 firedCount 와 컴파일러는 이름의 방법).각 통화를 PotentialMemoryLeaker 의 새 인스턴스를 만듭니퍼 클래스가 foo 유지 참조 방식에 의해의 대리자를 하나의 방법입니다.
지 않는 경우 참고 전체적인 개체를 소유하는 PotentialMemoryLeaker,그 모든 것은 쓰레기 수집됩니다.그렇지 않으면,당신은 설정할 수 있습니다 foo null 또는 빈 foo 의 이벤트 처리 목록을 작성하여 이:
foreach (var handler in AnEvent.GetInvocationList()) AnEvent -= handler;
물론 당신은에 액세스해야 MyObject 클래스의 개인 회원입니다.
예에서 같은 방식으로 정상적인 이벤트 처리할 수 있는 누수의 원인이됩니다.기 때문에 람다 실제로 변경:
someobject.SomeEvent += () => ...;
someobject.SomeEvent += delegate () {
...
};
// unhook
Action del = () => ...;
someobject.SomeEvent += del;
someobject.SomeEvent -= del;
그래서 기본적으로 그것은 단지 짧은 손해 우리가 무엇을 사용하에서 2.0 이러한 모든 년입니다.