2013-02-10 28 views
8

Tôi đang cố gắng tạo ứng dụng C# Winform sử dụng ZeroMQ (clrzmq .net bindings (x86) qua nuget) trong một pub/sub model.ví dụ về pub/sub zeromq với C# winform

Sau nhiều lần tìm kiếm, tôi chỉ có thể tìm các ví dụ C# độc lập trong đó mã sử dụng câu lệnh trong khi xử lý thư mới vô thời hạn. Khi tôi cố gắng sử dụng những ví dụ này, tôi không biết đặt mã, và nó chỉ chặn gui và mọi thứ khác.

Tôi không biết nếu nó không thể làm mà không sử dụng một chủ đề khác, nhưng tôi đã được ấn tượng rằng hành vi không đồng bộ của ZeroMQ có thể làm việc mà không cần mã hóa thêm chủ đề. Có lẽ tôi chỉ không biết nơi để đặt mã zeromq, hoặc có lẽ tôi thực sự cần một sợi.

Nếu ai đó có thể cung cấp một ví dụ về quán rượu/phụ đơn giản với hướng dẫn thực sự chèn mã vào ứng dụng mặc định C# sẽ rất được đánh giá cao.

Trả lời

7

Tôi giả sử bạn đang sử dụng clrzmq ZeroMq wrapper trong dự án của mình. Theo như tôi biết không thể nhận tin nhắn không chặn trong một vòng lặp đơn giản bằng cách sử dụng clrzmq, nó sẽ chặn vô thời hạn, trong một khoảng thời gian cụ thể (bằng cách cung cấp thời gian chờ cho phương thức nhận) hoặc cho đến khi bạn nhận được tin nhắn .

Tuy nhiên, nó là khá tầm thường để thiết lập một chuỗi để thăm dò ý kiến ​​các ổ cắm định kỳ và đẩy tin nhắn đến vào một Queue. Sau đó, bạn có thể sử dụng ví dụ một WinForms đơn giản Timer để khử tạp định kỳ bất kỳ thư đang chờ xử lý nào từ đó (được chia sẻ) Queue. Dưới đây là một ví dụ làm việc của một thuê bao luồng:

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

Từ Form bạn chỉ cần thăm dò ý kiến ​​Queue theo định kỳ (ví dụ này sử dụng một Forms Timer và chỉ cần gắn thêm các dữ liệu thông điệp tới một 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

Khi Tôi cố gắng sử dụng lớp ZeroMqSubscriber của bạn ở trên, Visual Studio nói rằng nó không thể tìm thấy không gian tên hoặc tên cho "ZmqContext" và một số trường hợp lớp khác mà bạn sử dụng. Có, tôi đã "sử dụng ZMQ". Bất kỳ ý tưởng? – uberdanzik

+0

Bạn có sử dụng liên kết clrzmq ZeroMq .NET không? Tôi có 'sử dụng ZeroMQ', không phải ZMQ. Ví dụ này bao gồm một liên kết đến dự án clrzmq (ở đầu bài viết). Tôi không chắc tại sao các ví dụ trên trang chính lại cho biết ZMQ, tôi nghĩ đó là tên không gian tên cũ. [Ví dụ về ZeroMq .NET] (https://github.com/imatix/zguide/tree/master/examples/C%23) sử dụng 'using ZeroMQ'. –

+0

Đúng, [nguồn clrzmq mới nhất] (https://github.com/zeromq/clrzmq/blob/master/src/ZeroMQ/ZmqContext.cs) sử dụng ** ZeroMQ ** làm vùng tên. –