2011-12-10 3 views
3

私はC#のWindowsを書いているが、シリアルポートからの入力を取得するアプリ、下図のように私は、サンプルコードを参照してください。EventHandlerの結果が新しくなると、あまりに多くのジャンクが発生しますか?

private void serialPort_DataReceived_1 (object sender, System.IO.Ports.SerialDataReceivedEventArgs e) 
{ 
    if (this.serialPort.IsOpen == true) 
     { 
      this.BeginInvoke(new EventHandler(delegate { this.textBox1.AppendText(this.serialPort.ReadExisting()); }));     
     } 

} 

コードがうまく動作します。しかし、私はBeginInvokeが何度も動いているのだろうかと疑問に思っています。この後も使用されていない多くの "new EventHandler"もメモリに作成されますか?

+0

「新しいEventHandlerをメモリに作成する」と思われる正当な理由があるのですか、まさに編集的なのですか? –

+0

いいえ、私は持っていません。私は、匿名の代理人を使ってプログラミングで悪い練習をすることができたのだろうかと思います。そのような '作成された'代議員を再利用することは不可能だと思われます。とにかく、すべての返信に感謝します。 :) – hongcc

答えて

3

エンベロープ計算の一部が戻ってきます。シリアルポートは115,000ボーの上にあり、11,500バイト/秒です。絶対最悪のケースでは、技術的に可能な個々のバイトごとにDataReceivedが発生していますが、Control.BeginInvoke()のオーバーヘッドを考えると非常に悪い結果に終ります。何かを修正する必要があります。

デリゲートオブジェクトには、32ビットバージョンのCLRでは32バイトが必要です。したがって、最大で11,500 x 32 = 368 KB /秒のヒープメモリを消費します。これはジェネレーション0のヒープにすべて割り当てられ、デリゲートオブジェクトがそのような短い時間生きるため、ジェネレーション0のガベージコレクションによって完全に削除されることがほぼ保証されます。

デフォルトのgen#0ヒープサイズは2メガバイトです。ヒープが圧迫されているときに成長し、gen 0コレクションがオブジェクトをgen 1に頻繁に移動させると、最大8メガバイト以上になります。この場合、デリゲートオブジェクトは非常に短命であるためそうはありません。 2メガバイトで作業しましょう。

したがって、ジェネレーション0のヒープがデレゲートオブジェクトだけで満たされ、ガベージコレクションが開始されるためには、2048/368 = 5.4秒かかります。 Gen 0のコレクションは平均5ミリ秒かかるが、移動する必要がある生き残ったオブジェクトが非常に少ないため、あまり必要としない可能性は非常に低い。

したがって、これらのオブジェクトの収集に費やされる処理時間の割合は、0.005/5.4 = 0.09%最悪の場合です。

これは観測できません。

3

これらの匿名の代理人のそれぞれは、完了するとガベージコレクションの対象となるため、多分大したことではありません。

あなたはそれについて本当に心配している場合、あなたは常にクラスのフィールドとして単一のEventHandlerを作成することができます。

EventHandler readFromSerialHandler; 

そして、あなたのコンストラクタでそう

readFromSerialHandler = (s, e) => 
      this.textBox1.AppendText(this.serialPort.ReadExisting()); 

に設定今すぐDataReceivedハンドラは次のようになります:

private void serialPort_DataReceived_1 (object sender, SerialDataReceivedEventArgs e) { 
    if (this.serialPort.IsOpen == true) { 
      this.BeginInvoke(this.readFromSerialHandler);     
    } 
} 
関連する問題