如何处理套接字阻塞的轮询器?

How to dispose a Poller with a blocked socket?

我只有一个套接字,它在发送帧时被阻塞,我想处理轮询器(以及与之相关的所有内容)。但是,我做不到——在 socket 上调用 dispose 会引发异常,而在 poller 上调用 dispose 会完全阻塞。

请注意,我正在使用 SendFrame 并且我可以使用 TrySendFrame,但此示例的目的是实际阻塞套接字并找到清理所有内容的方法。

示例:

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");
}

使用 NetMQ 3.3.3.4(目前我的主要版本)和 4.0.0.1 进行测试。

1) 始终归零 ZMQ_LINGER总是。就在 socket 实例化时,为了防止在正常终止 { .close() | .term() } 操作时无意中阻塞(无论是受控还是不受控的终止操作激活(因为你已经面对过它))。

2) 避免阻塞设计。 原则上。每个阻塞状态都会创建一个状态,在该状态下您的所有代码都将失去控制。明白了吗?