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 メモリ プロファイラを使用して、

ここに画像の説明を入力

オブジェクトをクリーンアップするための提案。

ありがとう。

4

1 に答える 1

5

mySend.BeginInvoke()を呼び出し続けます。したがって、ガベージコレクターは、スレッドプールスレッドのスタック上のmySendオブジェクトへの参照を常に確認します。したがって、それを収集しません。そしてもちろん、コードは永遠に実行され続けます。

このシナリオでEndInvoke()を呼び出さないのは悪い考えです。これは、BeginInvoke()の呼び出しごとに10分間リソースをリークします。デフォルトのリモーティングライフタイムであるリモーティングは、デリゲートのBeginInvoke()メソッドを実装する基礎となる配管です。

コードをクリーンアップするための提案を思い付くのは難しいですが、これを行うのはあまり意味がありません。while(true){}ループでスレッドを開始することもできます。それは間違いなくより効率的です。

于 2012-07-31T08:05:21.740 に答える