ZeroMQ上下文破坏导致轮询器到ETERM但不继续

Jas*_*son 2 c# dispose zeromq

我有一个非常简单的线程循环

public void ClientLoop(object AContext)
{
    var context = (ZMQ.Context) AContext;

    Socket client = CreateServerSocket(context);

    while (true)
    {
        try
        {
            Context.Poller(requestTimeout*1000, client);
        }
        catch (Exception e)
        {
            if (e.Errno == ETERM)
            {
                //Catch a termination error. 
                Debug.WriteLine("Terminated! 1");
                return;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

并且处理看起来如下

public void Dispose()
{
    _context.Dispose();
}
Run Code Online (Sandbox Code Playgroud)

创建客户端套接字时将linger设置为零,并在处理程序集中设置轮询器.套接字也是请求套接字.

一旦调用dispose,轮询器就会排除并进入try除块之外.然而,在处置后没有继续像我想的那样.这就是ZGuide如何处理上下文和套接字的破坏,但在这种情况下它似乎不起作用.

我错过了什么?

Gui*_*one 5

然而,在处置后没有继续像我想的那样.

你的意思是调用Dispose挂起/阻止?这是因为在从线程返回之前没有关闭客户端套接字.(我的下面的语法可能有误,但你明白了)

        if (e.Errno == ETERM)
        {
            //Catch a termination error. 
            Debug.WriteLine("Terminated! 1");
            client.Close();
            return;
        }
Run Code Online (Sandbox Code Playgroud)

将linger设置为0是不够的 - 这只是阻止套接字闭包阻塞.您仍必须关闭工作线程中的套接字以防止_context.Dispose()阻塞.

这就是ZGuide如何处理上下文和套接字的破坏......

嗯 - 这是真的,但文档中有一个重要的限定词:

我们将在下一章中讨论多线程,但是因为你们中的一些人会在你安全行走之前尝试运行,下面是在多线程ØMQ应用程序中进行干净退出的快速而肮脏的指南.

在文档的后面,他们描述了如何通过在每个线程中使用专用套接字来监听kill信号来进行干净关闭.考虑通过执行类似的操作来增强工作线程.通过这种方式,您可以通过向每个线程发送一条消息来请求每个线程自行关闭 - 每个线程然后退出其运行循环,在它的套接字上执行干净的关闭并退出.一旦所有线程都退出,您就可以安全地处理上下文而不会出现任何错误.