I have single socket, which is blocked on sending the frame and I would like to dispose poller ( and everything related to it ). However, I cannot do it -- calling dispose on socket throws an exception, and calling dispose on poller completely blocks.
Please note, I am using SendFrame
and I could use TrySendFrame
, but the purpose of this example is to actually block the socket and find a way how to clean up everything.
Example:
private Program()
{
const string address = "tcp://localhost:5000";
var socket = new DealerSocket();
socket.Options.SendHighWatermark = 1;
socket.Options.Identity = Encoding.ASCII.GetBytes(Guid.NewGuid().ToString("N"));
socket.Connect(address);
var poller = new NetMQPoller();
poller.Add(socket);
socket.SendReady += OnSendReady;
poller.RunAsync();
Thread.Sleep(5000);
Console.WriteLine("Disposing");
poller.Dispose(); // get stuck on this one
Console.WriteLine("Disposed");
}
private void OnSendReady(object sender, NetMQSocketEventArgs e)
{
Console.WriteLine("0");
e.Socket.SendFrame("hello");
Console.WriteLine("1");
e.Socket.SendFrame("hello"); // this will block
Console.WriteLine("2");
}
Tested with NetMQ 3.3.3.4 (my primary version for now) and 4.0.0.1.
1) Always zeroize ZMQ_LINGER
. Always. Right upon a socket
instantiation, so as to prevent otherwise inadvertent blocking on graceful termination { .close() | .term() }
operations ( be it a controlled or un-controlled activation of termination ops ( as you already have faced it ) ).
2) Avoid blocking designs. Principally. Each blocking state creates a state, in which all your code is out-of-control. Got it?