Прежде всего. Блокировка - это плохо, когда дело доходит до программирования сокетов. Решение @ AndrewKeith хорошо подходит для очередей команд и их отправки.
Вам нужно иметь идентификатор запроса, который вы можете поместить в другую очередь и отправить обратно с ответом. Вы можете сделать несколько текущих команд.
Простой псевдокод:
public void Send(ICommand command)
{
var myPacket = new CommandPacket {
Command = command,
RequestId = Guid.NewGuid()
};
_pendingCommands.Add(myPacket);
var buffer = Serialize(myPacket);
socket.Send(buffer);
}
public void OnReceive(IAsynResult ar)
{
var bytesRead = socket.EndRecieve(ar);
_inStream.Write(_readBuffer, 0, bytesRead);
if (GotCompletedPacket(_inStream))
{
var packet = Deserialize(_inStream);
var waitingCommand = _pendingCommands.FirstOrDefault(p => p.RequestId == packet.RequestId);
if (waitingCommand != null)
//got a reply to the command.
}
}
Я бы лично добавил делегата при вызове команды:
public void Send(ICommand command, ICommandHandler handler)
и вызывать этот обработчик при получении ответа.