c# - 在 ZeroMQ C# 中断开套接字

标签 c# multithreading sockets zeromq disconnect

我正在使用 ZeroMQ for Visual Studio 的 NuGet 包。我使用的版本是 3.0.0-rc1。

我已经搜索了很长一段时间,但仍然没能找到解决我的问题的“优雅”解决方案。我正在创建一个服务器 (ROUTER) 套接字,然后基本上等待任何数据到达该套接字。我通过创建一个轮询器并在无限循环中等待来做到这一点。我的问题是试图找出在我尝试关闭应用程序时如何中断对 Poll() 的调用。顺便说一句,下面的代码是在一个单独的线程中完成的,我将我的上下文传递给线程以创建套接字。

        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,但此时应用程序挂起并且永远不会返回。我假设它挂了,因为我还有一个 socket 打开。我还读到,通过将 Linger 标志设置为非常小的东西,套接字应该在调用上下文中的 Terminate 后关闭,但这种情况没有发生。

我有 catch 子句的原因是因为当我使用 2.0 版并在上下文中调用 Dispose() 时,我会收到一个异常并且我可以优雅地摆脱套接字,但我不再版本 3.0 出现异常。

所以我想知道我是否只是遗漏了什么?如果有更“优雅”的方法来关闭在它自己的线程中等待消息的套接字?

最佳答案

不是真的“优雅”,但古老而简单的方法是从同一个进程(不同线程)实际连接到您的监听套接字,因此您获得“事件”并在此时检查“关闭”标志。

这个 hack 的原始名称是“self-pipe trick”。

关于c# - 在 ZeroMQ C# 中断开套接字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23092981/

相关文章:

c# - 无法引用工具包

c# - 优化文件操作

c++ - CMSIS-RTOS 的 osMailFree() 返回一些地址而不是 osStatus 类型的值

node.js - 使用 JWT token 。有更好的方法吗?

java - 从数据包 header 设置 Java 字节数组大小

c# - SQLConnection 使用随机命名管道而不是 tcp

c# - 用于匹配重复的连续标点符号的正则表达式,但 3 个句点除外

c# - 仅通过 (int)from 和 (int)to 创建 List<int> 的优雅方式

c# - HttpClient.PostAsync ThreadPool 中没有足够的空闲线程来完成操作

c# - 如何使用udp从C#客户端与C服务器通信?