1

UdpClient (c++/cli) を使用しています。明らかな BeginReceive を使用してリスナーを開始します。

System::Void CUdpTransmitter::StartListener() {
  ...
  m_UdpClient->BeginReceive ( gcnew System::AsyncCallback(ReceiveCallback), this );
}

ReceiveCallback は、最後に新しい AsyncCallback を開始する必要があります。呼び出しごとに新しいものを割り当てるのではなく、メンバー変数に AsyncCallback を格納するパフォーマンス上の利点やその他の理由はありますか? スレッドセーフはどうですか?次のバリアントを比較します。

System::Void CUdpTransmitter::ReceiveCallback1( System::IAsyncResult ^ asyncResult ) {
  m_UdpClient->EndReceive();
  // parse received data (not time consumpting)
  ...
  if (! exit) {
    m_UdpClient->BeginReceive ( gcnew System::AsyncCallback(ReceiveCallback), self );
  }
}
public ref class CUdpTransmitter {
  AsyncCallback ^ m_callback; // store AsyncCallback in a member variable, it will be initized in constructor... gcnew System::AsyncCallback(ReceiveCallback2)
  System::Void CUdpTransmitter::ReceiveCallback2( System::IAsyncResult ^ asyncResult ) {
    m_UdpClient->EndReceive();
    // parse received data (not time consumpting)
    ...
    if (! exit) {
      // start receiving, reuse the member variable and avoid gcnew
      m_UdpClient->BeginReceive ( m_callback, self );
    }
  }
}

お時間とご回答ありがとうございます。

4

1 に答える 1

2

デリゲートはスレッド セーフなので、その心配はありません。(デリゲートは作成後は不変です。マルチキャスト デリゲートからデリゲートを追加または削除するメソッドは、実際には新しいマルチキャスト デリゲートを返します。)

デリゲート オブジェクトをインスタンス化し、ガベージ コレクションを行うと、パフォーマンスがわずかに低下します。したがって、このデリゲートを頻繁に使用する場合は、m_callback を使用してください。ただし、前述したように、1 秒間に数百万回実行しない限り、これは非常に小さなペナルティです。

これを頻繁に行うのではなく、コードをクリーンアップしてクラス メンバーの数を減らしたい場合は、毎回コールバックをインスタンス化してください。

于 2012-11-08T19:01:05.520 に答える