I have a question about at what point after a BeginAccept on a socket can I tell my listener thread that it can start accepting connections again.
This is the code I have:
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
then in my Async Callback:
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 ...
This is how they do it in the Asynchronous Server Socket Example on msdn.
But from what I have read
BeginAccept is not a blocking call. The blocking call is
EndAccept, and it blocks until there is a connection to accept.
So having the
mReadyToAcceptWaitHandle.Set();, to tell the listener thread to keep accepting connections, before EndAccept() seems odd to me because wouldn't that just cause it to keep opening
AcceptConnection handler threads (from what I've seen from execution, it doesn't seem to do this, but I don't know why?) that all just block on
Would it not be better to have
EndAccept, so that it only deals with accepting one connection at a time, and once it has accepted, but before it actually handles the communication on the connection.
Both ways seem to work, but I want to know which one is the correct way, and whether one way will have subtle negative side effects that the other doesn't.
What am I missing here?
Thanks in advance.
The blocking call is EndAccept, and it blocks until there is a connection to accept.
That's not an accurate description.
EndAccept is called from the callback of
BeginAccept when a connect request has been received from a client. You can call
BeginAccept again from the
BeginAccept callback to immediately accept another connection while establishing the (previous) connection you just received via
EndAccept (still in the connection callback).
So it is not actually necessary to use events at all to synchronize when to accept new connections. Simply call
BeginAccept again from the callback.