2

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

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

以及如下所示的处置

public void Dispose()
{
    _context.Dispose();
}

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

一旦 dispose 被调用,poller excepts 就会进入 try except 块。然而,处置后并没有像我想象的那样继续。这就是 ZGuide 所说的处理上下文和套接字破坏的方式,但是在这种情况下它似乎不起作用。

我错过了什么?

4

1 回答 1

5

然而,处置后并没有像我想象的那样继续。

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

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

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

这就是 ZGuide 所说的处理上下文和套接字破坏的方式......

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

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

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

于 2012-09-09T01:40:50.057 回答