2012-11-08 21 views
1

我正在使用UdpClient(C++/cli),我使用明顯的BeginReceive啓動我的偵聽器。在創建新成員變量時存儲AsyncCallback的性能優勢

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); 
    } 
    } 
} 

感謝您的時間和答案。

回答

1

代表是線程安全的,所以不用擔心。 (代理在創建之後是不可變的,任何添加或從多播代理中刪除代理的方法實際上都會返回一個新的多播代理。)

實例化委託對象和垃圾收集它們的性能損失很小,所以如果你非常頻繁地使用這個委託,然後使用m_callback。然而,正如我所說,除非你每秒做數百萬次,否則這是一個非常小的懲罰。

如果你不經常這樣做,並且你想清理你的代碼,並且有更少的班級成員閒逛,那麼請繼續實例化每次回調。

+0

嗯,我從6個攝像頭解析數據(VGA分辨率@ 30fps,灰度8bit),考慮到MTU 1500bytes,這意味着大約37000包/秒。根據你的回答,似乎不值得存儲m_callback。但無論如何,因爲缺乏經驗,我想知道,是否有可能以這種方式重用m_callback。 Thx回答。 – dousin