Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/285.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带有C#winform的zeromq发布/订阅示例_C#_.net_Winforms_Zeromq - Fatal编程技术网

带有C#winform的zeromq发布/订阅示例

带有C#winform的zeromq发布/订阅示例,c#,.net,winforms,zeromq,C#,.net,Winforms,Zeromq,我正在尝试创建一个C#Winform应用程序,该应用程序在发布/订阅模型中使用ZeroMQ(通过nuget的clrzmq.net绑定(x86)) 经过大量搜索,我只能找到独立的C#示例,其中代码使用while语句无限期地处理新消息。当我尝试使用这些示例时,我不知道将代码放在哪里,它只会阻塞gui和其他一切 我不知道不使用另一个线程是否是不可能的,但我的印象是ZeroMQ的异步行为可以在不编码额外线程的情况下工作。也许我只是不知道把zeromq代码放在哪里,或者我真的需要另一个线程 如果有人能提供

我正在尝试创建一个C#Winform应用程序,该应用程序在发布/订阅模型中使用ZeroMQ(通过nuget的clrzmq.net绑定(x86))

经过大量搜索,我只能找到独立的C#示例,其中代码使用while语句无限期地处理新消息。当我尝试使用这些示例时,我不知道将代码放在哪里,它只会阻塞gui和其他一切

我不知道不使用另一个线程是否是不可能的,但我的印象是ZeroMQ的异步行为可以在不编码额外线程的情况下工作。也许我只是不知道把zeromq代码放在哪里,或者我真的需要另一个线程


如果有人能提供一个简单的pub/sub示例,说明将代码实际插入默认C#winform应用程序的位置,我将不胜感激。

我假设您正在项目中使用。据我所知,使用clrzmq在一个简单的循环中不可能无阻塞地接收消息,它将无限期地阻塞,阻塞时间为特定的时间量(通过向receive方法提供超时),或者直到您收到消息为止

但是,设置一个线程定期轮询套接字并将传入消息推送到
队列
,这相当简单。然后,您可以使用一个简单的WinForms
计时器来定期从该(共享)
队列中取出任何挂起的消息。以下是线程订阅服务器的工作示例:

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

当我尝试使用上面的ZeroMqSubscriber类时,VisualStudio说它找不到“ZmqContext”和您使用的其他一些类实例的名称空间或名称。是的,我有“使用ZMQ”。有什么想法吗?你使用clrzmq ZeroMq.NET绑定吗?我使用的是ZeroMQ,而不是ZMQ。该示例包括一个指向clrzmq项目的链接(在文章的开头)。我不知道为什么主页上的示例会显示ZMQ,我认为这是旧的名称空间名称。使用ZeroMQ的用法
。是的,使用ZeroMQ作为名称空间。我正在通过nuget使用clrzmq.net绑定包(x86)…据说这是“入门”的推荐方法。我想有一些区别。好吧——Visual Studio的nuget软件包管理器只显示2.0版,除非您将下拉列表从“仅稳定”更改为“包含预发布”,然后显示3.0版进行更新,瞧,名称空间切换到ZeroMQ和BAM!没有更多的命名空间错误。
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);
}