0MQ: Comment utiliser ZeroMQ d'une manière threadsafe?

J'ai lu le ZeroMq guide et je suis tombé sur les éléments suivants:

Vous ne DEVEZ PAS partager ØMQ sockets entre
les threads. ØMQ sockets ne sont pas
des threads. Techniquement, c'est possible
pour ce faire, mais il exige des sémaphores,
des écluses ou des mutex. Cela permettra de rendre votre
application lente et fragile. La seule
lieu où il est à distance de sain d'esprit
partager sockets entre les threads sont en
liaisons de langage qu'il faut faire
la magie comme la collecte des ordures sur
sockets.

et plus tard:

Rappelez-vous: Ne pas utiliser ou de fermer les sockets, sauf dans le fil qui les a créés.

J'ai aussi compris que le ZeroMQ Context est thread-safe.

Si une classe s'inscrit à un événement d'une autre classe, dans .Net, cet événement pourrait être appelée à partir d'un thread différent de celui de l'auditeur a été créé.

Je pense qu'il y a seulement deux options pour être en mesure d'expédier quelque chose via ZeroMQ-prises de courant à partir de l'intérieur d'un gestionnaire d'événements:

  • Synchroniser le gestionnaire d'événements-invoquer-fil pour le fil de la ZeroMQ-Socket a été créé en
  • Créer un nouveau ZeroMQ-Socket /récupérer l'existant ZeroMQ-Socket pour le thread dans le gestionnaire d'événements en utilisant les threads ZeroMQ-Context

Il semble que la 0MQ-Guide pour décourager à la première, et je ne pense pas que la création d'une nouvelle ZeroMq-Socket pour chaque thread est performant /le chemin à parcourir.

Ma Question:
Qu'est-ce que le modèle correct (la façon dont il est censé le faire) de publier des messages via 0MQ sein d'un gestionnaire d'événements?

De même, les auteurs du guide ont la ZeroMQ de Liaison pour .Net à l'esprit quand ils ont écrit:

Le seul
lieu où il est à distance de sain d'esprit
partager sockets entre les threads sont en
liaisons de langage qu'il faut faire
la magie comme la collecte des ordures sur
les sockets. ?

Voici quelques samplecode pour souligner mon problème/question:

public class ExampleClass
{
    public event EventHandler<ByteEventArgs> SomethinIsCalledFromAnotherThread;
}

public class ByteEventArgs : EventArgs
{
    public byte[] BytesToSend;
}


public class Dispatcher
{
    ZMQ.Context ctx;

    public Dispatcher(ZMQ.Context mqcontext, ExampleClass exampleClassInstance)
    {
        this.ctx = mqcontext;
        exampleClassInstance.SomethinIsCalledFromAnotherThread += new EventHandler<ByteEventArgs>(exampleClass_SomethinIsCalledFromAnotherThread);
    }

    void exampleClass_SomethinIsCalledFromAnotherThread(object sender, ByteEventArgs e)
    {
        //this method might be called by a different thread. So I have to get a new socket etc?
        using (var socket = ctx.Socket(ZMQ.SocketType.PUSH))
        {
            //init socket etc..... and finally: 
            socket.Send(e.BytesToSend);
        }
        //isn't that too much overhead?
    }
}

source d'informationauteur tobsen