在 ZeroMQ C# 中断开套接字连接

3
我正在使用Visual Studio的ZeroMQ NuGet包。我使用的版本是3.0.0-rc1。
我已经搜索了相当长的时间,但仍然没有找到一个“优雅”的解决方案来解决我的问题。我正在创建一个服务器(ROUTER)套接字,然后基本上等待在该套接字上到达任何数据。我通过创建一个轮询器并在无限循环中等待来实现这一点。我的问题是如何在尝试关闭应用程序时打破对Poll()的调用。顺便说一句,下面的代码是在单独的线程中完成的,我正在将我的上下文传递给线程,以便创建Socket。
        using (ZmqSocket server = cntxt.CreateSocket(ZeroMQ.SocketType.ROUTER))
        {
            string strSocketAddress = String.Format("tcp://{0}:{1}", strIPAddress, nPort.ToString());

            try
            {
                server.Linger = TimeSpan.FromMilliseconds(1); ;

                server.Bind(strSocketAddress);

                server.ReceiveReady += server_ReceiveReady;

                ZeroMQ.Poller poller = new Poller(new List<ZmqSocket> {server});

                while (true)
                {
                    poller.Poll();
                }

            }
            catch (ZmqException zex)
            {
                server.Disconnect(strSocketAddress);

                server.Close();

                server.Dispose();
            }
        }

这里一切都按预期工作,当我在套接字上接收到数据时,确实会收到事件。但是当我想要关闭应用程序时,我无法弄清楚如何跳出循环。我知道我可以在轮询中设置超时并放置某种标志来表示我正在关闭,但我希望有一个“更好”的解决方案。
现在发生的情况是,当我想要关闭时,我在上下文中调用Terminate,但此时应用程序挂起并且永远不会返回。我假设它挂起是因为我仍然有一个套接字打开。我还读到,通过将Linger标志设置为非常小的值,套接字应该在调用上下文上的Terminate后关闭,但这并没有发生。
我添加catch子句的原因是因为当我使用版本2.0并在上下文上调用Dispose()时,我会收到异常并且可以优雅地摆脱套接字,但是在3.0版本中我不再收到异常。
所以我想知道我是否遗漏了什么?如果有一种更“优雅”的方法来关闭等待消息的套接字线程吗?
1个回答

2

并不是非常“优雅”,但是一种古老而简单的方法是从同一进程(不同线程)连接到您的监听套接字,以便在那一点上获取“事件”并检查“关闭”标志。

这种黑客技巧的原始名称是“自管道技巧”。


这本质上与在Poll()方法上设置超时并检查关闭标志是一样的,对吗?我正在理解self-pipe技巧。我唯一能看到的区别是,使用self-pipe技巧时,只有在实际收到消息(来自自己或实际客户端)时,Poll方法才会返回。这正确吗?感谢您抽出时间回答。 - DanScott0806

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接