Это зависит от того, насколько умный компилятор.
В вашем случае, да, this
определенно будет поддерживаться делегатом в течение всего срока его жизни.
Давайте рассмотрим случай, который определенно НЕ сохранит this
в живых:
private void Receive()
{
ATcpState state = this.state;
// create the callback here, in order to use in dynamic
AsyncCallback ReceiveCallback = delegate(IAsyncResult ar)
{
try
{
// Read data from the remote device.
state.BytesReceived = state.Socket.EndReceive(ar);
}
catch (Exception e)
{
// ...
}
};
try
{
state.Socket.BeginReceive(state.Buffer, 0, state.BufferSize, 0,
ReceiveCallback, null);
}
catch (Exception e)
{
// ...
// ...
}
}
А затем случай, когда оптимизация компилятора может повлиять на поведение коллекции:
private readonly ATcpState state = new ATcpState();
private void Receive()
{
// create the callback here, in order to use in dynamic
AsyncCallback ReceiveCallback = delegate(IAsyncResult ar)
{
try
{
// Read data from the remote device.
state.BytesReceived = state.Socket.EndReceive(ar);
}
catch (Exception e)
{
// ...
}
};
try
{
state.Socket.BeginReceive(state.Buffer, 0, state.BufferSize, 0,
ReceiveCallback, null);
}
catch (Exception e)
{
// ...
// ...
}
}
Единственный оставшийся вопрос: каков срок службы этого делегата? Является ли ожидающая операция корнем, или мы просто имеем циклическую ссылку между делегатом, возможно this
, state
, state.Socket
, и операцией? Если ни один из них не доступен из корня, тогда весь пакет может быть завершен (что закроет сокет, отменяя операцию).
По крайней мере для некоторых объектов, использующих шаблон BeginReceive
/ EndReceive
, операция НЕ является корневой
Похоже, что для вашего случая (Socket.BeginReceive
), внутри System.Net.Sockets.BaseOverlappedAsyncResult.PinUnmanagedObjects
.
создается корень.