在ZeroMQ C#中断开套接字

时间:2014-04-15 19:42:31

标签: c# multithreading sockets zeromq disconnect

我正在使用ZeroMQ的NuGet包用于Visual Studio。我使用的版本是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 个答案:

答案 0 :(得分:2)

不是真的&#34;优雅&#34;,但是老而简单的方法是从同一个进程(不同的线程)实际连接到你的侦听套接字,所以你得到了&#34;事件&#34;并检查&#34;关闭&#34;那时的旗帜。

这个黑客的原始名称是&#34;自我管道技巧&#34;。