C# 如何在c中从工作线程关闭ZMQ QueueDevice#
第一次使用ZMQ,我正在尝试设置一个进程来处理许多getimage请求。当我调试时会发生一些异常,我试图修复这些异常,并实现一种停止QueueDevice的方法,终止所有线程并优雅地退出C# 如何在c中从工作线程关闭ZMQ QueueDevice#,c#,multithreading,zeromq,netmq,C#,Multithreading,Zeromq,Netmq,第一次使用ZMQ,我正在尝试设置一个进程来处理许多getimage请求。当我调试时会发生一些异常,我试图修复这些异常,并实现一种停止QueueDevice的方法,终止所有线程并优雅地退出 receiver.Connect(后端绑定地址);在NetMQ.dll中发生类型为“NetMQ.InvalidException”的未处理异常,错误代码为NetMQ.zmq.ErrorCode.EINVAL。为什么这个异常不停止线程的进一步执行 我已尝试将QueueDevice设置为静态字段,并在shutdow
[TestMethod]
public void ProgramStartupShutdownTest()
{
var mockClientWrapper = new Mock<IClient>(MockBehavior.Strict);
var target = new SocketListener(2, mockClientWrapper.Object);
var task = Task.Factory.StartNew(() => target.StartListening("tcp://localhost:81"));
using (var client = NetMQContext.Create())
{
var socket = client.CreateRequestSocket();
socket.Connect("tcp://localhost:81");
var m = new NetMQMessage(new ShutdownMessage().CreateMessageFrames());
socket.SendMessage(m);
}
var timedout = task.Wait(200);
Assert.IsTrue(timedout);
}
[TestMethod]
公共无效程序StartupShutdownTest()
{
var mockClientWrapper=newmock(MockBehavior.Strict);
var target=newsocketlistener(2,mockClientWrapper.Object);
var task=task.Factory.StartNew(()=>target.StartListening(“tcp://localhost:81"));
使用(var client=NetMQContext.Create())
{
var socket=client.CreateRequestSocket();
插座。连接(“tcp://localhost:81");
var m=new NetMQMessage(new ShutdownMessage().CreateMessageFrames());
socket.SendMessage(m);
}
var timedout=task.Wait(200);
Assert.IsTrue(timedout);
}
我正在使用的代码
private const string BackendBindAddress = "inproc://workers";
public SocketListener(int numberOfWorkers, IClient client )
{
numberOfThreads = numberOfWorkers;
_client = client;
}
public void StartListening(string address)
{
StartZeroMQ(address, context =>
{
for (var i = 0; i <= numberOfThreads; i++)
{
var t = new Thread(WorkerRoutine);
t.Start(
new WorkerParamters
{
Context = context,
Client = _client
}
);
}
});
}
private void StartZeroMQ(string address, Action<NetMQContext> setupWorkers)
{
using (var context = NetMQContext.Create())
{
var queueDevice = new QueueDevice(context, address, BackendBindAddress, DeviceMode.Blocking);
setupWorkers(context);
queueDevice.Start();
}
}
struct WorkerParamters
{
public NetMQContext Context;
public IClient Client;
}
private static void WorkerRoutine(object startparameter)
{
var wp = (WorkerParamters) startparameter;
var client = wp.Client;
using (var receiver = wp.Context.CreateResponseSocket())
{
receiver.Connect(BackendBindAddress);
var running = true;
while (running)
{
var message = receiver.ReceiveMessage();
var letter = Message.ParseMessageFrame(message,
imageMessage => GetImage(imageMessage, client),
videoMessage => GetVideo(videoMessage, client),
shutdownMessage =>
{
running = false;
return true;
});
receiver.Send(letter.ToJson(), Encoding.Unicode);
}
}
}
private const string backendbinddress=”inproc://workers";
公共SocketListener(int numberOfWorkers,IClient客户端)
{
numberOfThreads=numberOfWorkers;
_客户=客户;
}
公共侦听(字符串地址)
{
StartZeroMQ(地址,上下文=>
{
对于(var i=0;i GetImage)(imageMessage,客户端),
videoMessage=>GetVideo(videoMessage,客户端),
关机消息=>
{
运行=错误;
返回true;
});
Send(letter.ToJson(),Encoding.Unicode);
}
}
}
为了克服这个问题,我在设备中添加了一个初始化方法,在启动工人之前调用它,在调用工人之后启动设备
您可以从中获取代码(您需要从存储库编译项目),稍后我将添加一个pull请求
你也可以手工编写设备逻辑,它不应该很复杂。我得到了一半的答案,inproc协议要求在你连接到它之前绑定套接字。谢谢,我正在考虑编写它,但在几个月后,当我的zmq知识变得更粗糙时,我不得不继续维护它。也就是说,我不想学习如何使用它在我所学的基础上使用民意测验。