При попытке отправить сообщение для очереди через вызов BeginSend, похоже, он ведет себя как блокирующий вызов.
Конкретно у меня есть:
public void Send(MyMessage message)
{
lock(SEND_LOCK){
var state = ...
try {
log.Info("Begin Sending...");
socket.BeginSend(message.AsBytes(),0, message.ByteLength, SocketFlags.None,
(r) => EndSend(r), state);
log.Info("Begin Send Complete.");
}
catch (SocketException e) {
...
}
}
}
Обратный вызов будет выглядеть примерно так:
private void EndSend(IAsyncResult result) {
log.Info("EndSend: Ending send.");
var state = (MySendState) result.AsyncState;
...
state.Socket.EndSend(result, out code);
log.Info("EndSend: Send ended.");
WaitUntilNewMessageInQueue();
SendNextMessage();
}
Большую часть времени это работает нормально, но иногда зависает. Регистрация указывает, что это происходит, когда BeginSend en EndSend исполняются в том же потоке . WaitUntilNewMessageInQueue блокируется до тех пор, пока в очереди не появится новое сообщение, поэтому при отсутствии нового сообщения оно может ждать некоторое время.
Насколько я могу судить, это не должно быть проблемой, но в некоторых случаях блоки BeginSend вызывают ситуацию взаимоблокировки, когда EndSend блокирует WaitUntilNewMessageInQueue (ожидается), но Send блокируется на BeginSend в ответ, так как кажется, что он ожидает обратного вызова EndSend te (не ожидается).
Такое поведение было не тем, чего я ожидал. Почему BeginSend иногда блокируется, если обратный вызов не возвращается своевременно?