I have a very simple thread loop
public void ClientLoop(object AContext)
{
var context = (ZMQ.Context) AContext;
Socket client = CreateServerSocket(context);
while (true)
{
try
{
Context.Poller(requestTimeout*1000, client);
}
catch (Exception e)
{
if (e.Errno == ETERM)
{
//Catch a termination error.
Debug.WriteLine("Terminated! 1");
return;
}
}
}
}
And a dispose that looks like the following
public void Dispose()
{
_context.Dispose();
}
The client socket is created with linger set to zero and a poller in handler set. The socket is also a request socket.
Once the dispose is called the poller excepts and falls into the try except block. However after the dispose doesn’t continue like I thought it would. This is how the ZGuide says to handle destruction of the context and sockets however it doesn’t seem to be working in this case.
What have I missed?
You mean the call to Dispose hangs/blocks? That is because you did not close the client socket before you return from the thread. (My syntax below may be wrong but you get the idea)
Setting linger to 0 is not enough – that just prevents the socket closure from blocking. You must still close the socket in your worker thread to prevent the _context.Dispose() from blocking.
Well – that’s true but there is an important qualifier in the document:
Later in the document they describe how to do a clean shutdown by having a dedicated socket in each thread which listens to a kill signal. Consider enhancing your worker thread by doing something similar. This way you can request each thread to shut itself down by sending each thread a message – each thread then exits its run loop, does a clean close on it’s socket(s) and exits. Once all threads have exited you can safely dispose of the context without having any errors.