2016-12-01 1 views
1

J'ai quelques problèmes avec le serveur multi-thread basé sur netMQ 4.0. J'ai essayé d'utiliser http://zguide.zeromq.org/cs:mtserver, mais il n'y a pas de contexte sur netMQ 4.0.netMQ 4.0 multithreading

J'ai essayé:

for (var i = 0; i < workerCount; ++i) 
{ 
    new Thread(() => Worker(connStr.Value)).Start(); 
} 

//... 
private void Worker(string connStr) 
{ 
    using (var socket = new DealerSocket(connStr)) 
    { 
     while (true) 
     { 
      var msg = socket.ReceiveMultipartMessage(); 
      //... 
     } 
    } 
} 

mais j'obtiens l'erreur:

NetMQ.TerminatingException: CheckContextTerminated

et oui, il est mis fin.

Comment créer un contexte dans netMQ 4.0 ou comment créer un serveur multithread en utilisant netMQ 4.0?

Répondre

1

Si vous utilisez la version .NET 4.0 ou plus, l'approche de la création Thread est obsolète et ne doit pas être utilisé de telle manière - si votre workerCount est assez élevé et que vous aren Ne fournissant aucune logique de planificateur, votre performance pourrait se dégrader de manière significative au lieu de bénéficier.

Ce que vous pouvez faire à la place de votre approche à l'aide TPL:

  1. Vous pouvez facilement remplacer vos threads de travail avec LongRunning tasks.
  2. Vous devriez probablement introduire le CancellationToken pour que vos travailleurs les arrêtent correctement.

Donc, votre code pourrait être quelque chose comme ceci:

/// field in your class 
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); 

using (var clients = new RouterSocket(connStr.Value)) 
using (var workers = new DealerSocket()) 
{ 
    workers.Bind("inproc://workers"); 
    for (var i = 0; i < workerCount; ++i) 
    { 
     Task.Factory.StartNew(Worker 
      , cancellationTokenSource.Token 
      , TaskCreationOptions.LongRunning 
      , TaskScheduler.Default); 
    } 
    var prx = new Proxy(clients, workers); 
    prx.Start(); 
} 

private void Worker() 
{ 
    using (var socket = new ResponseSocket()) 
    { 
     socket.Connect("inproc://workers"); 
     while (!cancellationTokenSource.Token.IsCancellationRequested) 
     { 
      //... 
     } 
     // Cancel the task and exit 
     cancellationTokenSource.Token.ThrowIfCancellationRequested(); 
    } 
} 

Pour simplifier, vous pouvez passer le CancellationToken en tant que paramètre à votre méthode Worker.

1

solution correcte:

using (var clients = new RouterSocket(connStr.Value)) 
using (var workers = new DealerSocket()) 
    { 
     workers.Bind("inproc://workers"); 
      for (var i = 0; i < workerCount; i++) 
      { 
       new Thread(Worker).Start(); 
      } 
      var prx = new Proxy(clients, workers); 
      prx.Start(); 
      } 

private void Worker() 
    { 
     using (var socket = new ResponseSocket()) 
     { 
      socket.Connect("inproc://workers"); 
      while (true) 
      { 
       //... 
      } 
     } 
    }