2012-07-30 4 views
4
public delegate void SendCallbackType(); 

    public class SenderBase 
    { 
     SenderBase() 
     { 
     mySend = new SendCallbackType(SendData); 
     mySend.BeginInvoke(SendCallback, null); 
     } 

    void SendData() 
    {    
     // process/sending data 
    } 

    void SendCallback(IAsyncResult ar) 
    {  
     **SendCallbackType worker = (SendCallbackType)((AsyncResult)ar).AsyncDelegate; 
     worker.EndInvoke(ar);** 

     //Above code is mandatory ? Working fine without them. 

     mySend.BeginInvoke(SendCallback, null); 

} 

// Test 
    Dictionary<SenderBase> SenderCollection = new Dictionary(); 
    SenderCollection.Add(new SenderBase()); 
    SenderCollection.Remove(0); 
// Add and remove seven times 

개체 (SenderBase)는 가비지 수집되지 않습니다. 그들은 다음 세대로 계속 움직이고 있습니다. RedAnts 메모리 프로파일 러를 사용 콜백이있는 대리인의 메모리 누수

,

enter image description here

어떤 제안 개체를 정리합니다.

감사합니다.

+1

비슷한 질문은 http://stackoverflow.com/questions/1774202/not-calling-delegate-endinvoke-can-cause-memory-leak-a-myth를 참조하십시오. 대리자와 사용하는 클래스가 같은 수명을 공유하는 한 메모리 누수가 없습니다. –

+0

메모리 누수가 없으면 EndInvoke()를 사용할 필요가 없습니까? –

+0

SendCallback()은 약간 재귀 적으로 보입니다 ... –

답변

5

계속 mySend.BeginInvoke()를 호출합니다. 따라서 가비지 수집기는 항상 스레드 풀 스레드 스택에서 mySend 객체에 대한 참조를 봅니다. 따라서 수집하지 않을 것입니다. 코드는 영원히 계속 실행됩니다.

이 시나리오에서 EndInvoke()를 호출하지 않는 것은 잘못된 생각이므로 각 BeginInvoke() 호출에 대해 10 분 동안 리소스가 누출됩니다. 기본 Remoting 수명 인 Remoting은 대리자의 BeginInvoke() 메서드를 구현하는 기본 구성 요소입니다.

코드를 정리하기위한 제안을하기가 어렵지만이 작업을 수행하는 것은별로 의미가 없습니다. while (true) {} 루프가있는 스레드를 시작할 수도 있습니다. 그것은 확실히 더 효율적 일 것입니다.

+0

답장을 보내 주셔서 감사합니다. 여기에 재귀가 필요합니다. 대리인 (ThreadPool 스레드 사용) 오버 헤드를 추가/사전에서 인스턴스를 제거하는 경우 생각. 약 900 개의 개체가 응용 프로그램 수명 동안 추가됩니다. 그리고 endinvoke(), 나는 예외를 캐스팅하고 싶지 않다. 예외는 senddata 내부에 잡히고 (이벤트를 통해 올리지 않음)), 콜백 호출시 senddata가 완료된다. endinvoke에 대한 다른 이유가 있습니까? –

+0

인스턴스를 제거한 후 스레드 풀 스레드가 자동으로 종료되었습니다. 사전에서 개체를 제거한 후 나는 더 이상 그것을 필요로하지 않는다. 나는 델리게이트를 시도했다. 그러나 여전히 동일합니다. –

+1

귀하의 의견은 귀하의 코드만큼이나 분분합니다. 내가 너를 도울 수 있다고 생각하지 않아. –