我正在尝试创建一个在发布/订阅模型中使用 ZeroMQ(通过 nuget 的 clrzmq .net 绑定(bind) (x86))的 C# Winform 应用程序。
经过大量搜索,我只能找到独立的 C# 示例,其中代码使用 while 语句无限期地处理新消息。当我尝试使用这些示例时,我不知道将代码放在哪里,它只会阻止 gui 和其他所有内容。
我不知道如果不使用另一个线程是不是不可能,但我的印象是 ZeroMQ 的异步行为可以在不编写额外线程的情况下工作。也许我只是不知道将 zeromq 代码放在哪里,或者我真的需要另一个线程。
如果有人可以提供一个简单的 pub/sub 示例,说明将代码实际插入默认 C# winform 应用程序的位置,我们将不胜感激。
最佳答案
我假设您使用的是 clrzmq ZeroMq wrapper在你的项目中。据我所知,不可能在使用 clrzmq 的简单循环中非阻塞地接收消息,它将无限期地阻塞一段特定的时间(通过为接收方法提供超时)或直到您收到一条消息.
但是,设置线程以定期轮询套接字并将传入消息推送到队列
是相当简单的。然后,您可以使用例如一个简单的 WinForms Timer
定期从该(共享)Queue
中取出任何未决消息。这是一个线程订阅者的工作示例:
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();
}
}
}
从 Form
您只需定期轮询队列(此示例使用 Forms Timer
并将消息数据简单地附加到 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);
}
关于c# - 使用 C# winform 的 zeromq pub/sub 示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14794393/