2013-02-10 18 views
8

Próbuję utworzyć aplikację Winfig C#, która używa ZeroMQ (clrzmq .net binding (x86) przez nuget) w modelu pub/sub.przykłady zeromq pub/sub z C# winform

Po wielu poszukiwaniach mogę znaleźć tylko samodzielne przykłady C#, w których kod używa instrukcji while do przetwarzania nowych wiadomości w nieskończoność. Kiedy próbuję użyć tych przykładów, nie wiem, gdzie umieścić kod, a to po prostu blokuje GUI i wszystko inne.

Nie wiem, czy nie można tego zrobić bez użycia innego wątku, ale miałem wrażenie, że asynchroniczne zachowania ZeroMQ mogą działać bez kodowania dodatkowych wątków. Być może po prostu nie wiem, gdzie umieścić kod zeromq, a może naprawdę potrzebuję innego wątku.

Jeśli ktoś mógłby podać prosty pub/podrzędny przykład z instrukcjami, gdzie faktycznie wstawić kod do domyślnej aplikacji WinFile C#, byłby bardzo doceniony.

Odpowiedz

7

Zakładam, że korzystasz z clrzmq ZeroMq wrapper w swoim projekcie. O ile mi wiadomo, nie można odbierać wiadomości bez blokowania w prostej pętli przy użyciu clrzmq, będzie ona blokować albo na czas nieokreślony, przez określony czas (przez podanie limitu czasu do metody odbioru), albo aż do otrzymania wiadomości .

Jednak dość trywialnie jest ustawić wątek, aby okresowo odpytywać gniazdo i przekazywać wiadomości przychodzące na numer Queue. Możesz następnie użyć na przykład prostego WinForms Timer, aby okresowo usuwać wszystkie oczekujące wiadomości z tego (udostępnionego) Queue. Oto przykład pracy z gwintowaną abonenta:

public class ZeroMqSubscriber 
{ 
    private readonly ZmqContext _zmqContext; 
    private readonly ZmqSocket _zmqSocket; 
    private readonly Thread _workerThread; 
    private readonly ManualResetEvent _stopEvent = new ManualResetEvent(false); 
    private readonly object _locker = new object(); 
    private readonly Queue<string> _queue = new Queue<string>(); 

    public ZeroMqSubscriber(string endPoint) 
    { 
     _zmqContext = ZmqContext.Create(); 
     _zmqSocket = _zmqContext.CreateSocket(SocketType.SUB); 
     _zmqSocket.Connect(endPoint); 
     _zmqSocket.SubscribeAll(); 

     _workerThread = new Thread(ReceiveData); 
     _workerThread.Start(); 
    } 

    public string[] GetMessages() 
    { 
     lock (_locker) 
     { 
      var messages = _queue.ToArray(); 
      _queue.Clear(); 
      return messages; 
     } 
    } 

    public void Stop() 
    { 
     _stopEvent.Set(); 
     _workerThread.Join(); 
    } 

    private void ReceiveData() 
    { 
     try 
     { 
      while (!_stopEvent.WaitOne(0)) 
      { 
       var message = _zmqSocket.Receive(Encoding.UTF8, 
           new TimeSpan(0, 0, 0, 1)); 
       if (string.IsNullOrEmpty(message)) 
        continue; 

       lock (_locker) 
        _queue.Enqueue(message); 
      } 
     } 
     finally 
     { 
      _zmqSocket.Dispose(); 
      _zmqContext.Dispose(); 
     } 
    } 
} 

Od Form po prostu sondować kolejki okresowo (w tym przykładzie używa Forms Timer i po prostu dołącza dane wiadomości do Textbox):

private readonly ZeroMqSubscriber _zeroMqSubscriber = 
     new ZeroMqSubscriber("tcp://127.0.0.1:5000"); 

void ReceiveTimerTick(object sender, EventArgs e) 
{ 
    var messages = _zeroMqSubscriber.GetMessages(); 
    foreach (var message in messages) 
     _textbox.AppendText(message + Environment.NewLine); 
} 
+0

Kiedy Próbuję użyć twojej klasy ZeroMqSubscriber powyżej, Visual Studio twierdzi, że nie może znaleźć przestrzeni nazw lub nazwy dla "ZmqContext" i innych instancji klas, których używasz. Tak, mam "używanie ZMQ". Jakieś pomysły? – uberdanzik

+0

Czy używasz wiązania clrzmq ZeroMq .NET? Mam 'przy użyciu ZeroMQ', a nie ZMQ. Przykład zawiera link do projektu clrzmq (na początku postu). Nie jestem pewien, dlaczego przykłady na stronie głównej mówią ZMQ, myślę, że jest to stara nazwa przestrzeni nazw. Przykłady [ZeroMq .NET] (https://github.com/imatix/zguide/tree/master/examples/C%23) używają 'używając ZeroMQ'. –

+0

Tak, [najnowsze źródło clrzmq] (https://github.com/zeromq/clrzmq/blob/master/src/ZeroMQ/ZmqContext.cs) używają ** ZeroMQ ** jako przestrzeni nazw. –