У меня есть вопрос о том, в какой момент после BeginAccept в сокете я могу сообщить моему потоку прослушивателя, что он может снова начать принимать соединения.
Это код, который у меня есть:
while(!mStopWaitHandle.WaitOne(0, false)) // <-- Manual Reset event to check if the service has stopped.
{
Logging.Debug("Waiting for a connection...");
socket.BeginAccept(new AsyncCallback(AcceptConnection), socket);
mReadyToAcceptWaitHandle.WaitOne(); // <-- AutoResetEvent to block until I can continue accepting connections
}
затем в моем асинхронном обратном вызове:
private void AcceptConnection(IAsyncResult ar)
{
mReadyToAcceptWaitHandle.Set(); // <-- Tell the listener thread to start accepting connections again
Socket socket = (Socket)ar.AsyncState;
Socket workerSocket = socket.EndAccept(ar);
... handle connection on workerSocket ...
}
Вот как они это делают в асинхронном сокете сервера Пример на msdn.
Но из того, что я прочитал, BeginAccept
не является блокирующим вызовом. Блокирующий вызов — EndAccept
, и он блокируется до тех пор, пока не появится соединение для принятия.
Таким образом, наличие mReadyToAcceptWaitHandle.Set();
, чтобы сообщить потоку прослушивателя продолжать принимать соединения, до того, как EndAccept() кажется мне странным, потому что разве это не приведет к тому, что он просто продолжит открывать потоки обработчика AcceptConnection
(из того, что я видел при выполнении, это не кажется, не делают этого, но я не знаю, почему?), что все просто блокируется на EndAccept
?
Не лучше ли было бы иметь mReadyToAcceptWaitHandle.Set();
после EndAccept
, чтобы он имел дело только с приемом одного соединения за раз, и после того, как он принят, но до того, как он фактически обработает связь по соединению.
Кажется, что оба способа работают, но я хочу знать, какой из них правильный, и будет ли один способ иметь тонкие негативные побочные эффекты, которых нет у другого.
Что мне здесь не хватает?
Заранее спасибо.