Повышение производительности при сохранении AsyncCallback в переменной-члене против создания новой
Я использую 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 );
}
}
}
Спасибо за ваше время и ваши ответы.
1 ответ
Делегаты являются потокобезопасными, так что об этом не стоит беспокоиться. (Делегаты остаются неизменными после создания, любой метод, который добавляет или удаляет делегата из делегата многоадресной рассылки, фактически возвращает новый делегат многоадресной рассылки.)
Существует очень незначительное снижение производительности для создания экземпляров объектов делегатов и их сбора мусора, поэтому, если вы используете этот делегат очень часто, тогда используйте m_callback. Однако, как я уже сказал, это очень незначительное наказание, если вы не делаете это несколько миллионов раз в секунду.
Если вы делаете это не часто, и вы хотите очистить свой код и иметь меньше учеников, оставайтесь в стороне и каждый раз создайте экземпляр обратного вызова.