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 を 0 に設定し、ポーラー in ハンドラーを設定して作成されます。ソケットはリクエストソケットでもあります。

dispose が呼び出されると、ポーラーの 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 アプリケーションでクリーンな終了を作成するための簡単で汚いガイドです。

ドキュメントの後半で、kill シグナルをリッスンする各スレッドに専用のソケットを用意して、クリーン シャットダウンを行う方法について説明しています。同様のことを行って、ワーカー スレッドを拡張することを検討してください。このようにして、各スレッドにメッセージを送信することで、各スレッドにシャットダウンを要求できます。各スレッドは実行ループを終了し、ソケットを完全に閉じて終了します。すべてのスレッドが終了すると、エラーが発生することなくコンテキストを安全に破棄できます。

于 2012-09-09T01:40:50.057 に答える