具有回调的代理上的内存泄漏

时间:2012-07-30 06:44:54

标签: c# memory-leaks delegates callback

 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 Memory Profiler,

enter image description here

清理对象的任何建议。

感谢。

1 个答案:

答案 0 :(得分:5)

你一直在调用mySend.BeginInvoke()。因此,垃圾收集器总是在线程池线程的堆栈上看到对mySend对象的引用。因此不会收集它。当然,代码一直在运行。

在这种情况下不调用EndInvoke()是一个坏主意,它为每个BeginInvoke()调用泄漏资源10分钟。默认的远程处理生命周期,远程处理是实现委托的BeginInvoke()方法的底层管道。

很难提出清理代码的建议,这样做没有多大意义。你也可以使用while(true){}循环启动一个线程。这肯定会更有效率。