使用ZeroMQ QueueDevice(clrzmq)时,如何在C#中设置Linger套接字选项?
我试图修改ZeroMQ多线程服务示例(),以便套接字不会在关闭时无限期地逗留。我不知道如何通过QueueDevice接口设置两个套接字的Linger值。在其他示例中,我只是为套接字设置了“Linger”选项,当上下文关闭时,它们立即退出。在我当前的程序中,工作线程关闭,但主线程无限期挂起。。。这可能与使用SetSocketOption一样简单,但我还不了解该方法的LINQ语法,而且“SocketOption”枚举不是公共的 注意:我正在使用Visual Studio 2013 Express,其中包含通过NuGet获得的clrzmq的3.0.0-rc1,使用以下命令:使用ZeroMQ QueueDevice(clrzmq)时,如何在C#中设置Linger套接字选项?,c#,multithreading,linq,sockets,zeromq,C#,Multithreading,Linq,Sockets,Zeromq,我试图修改ZeroMQ多线程服务示例(),以便套接字不会在关闭时无限期地逗留。我不知道如何通过QueueDevice接口设置两个套接字的Linger值。在其他示例中,我只是为套接字设置了“Linger”选项,当上下文关闭时,它们立即退出。在我当前的程序中,工作线程关闭,但主线程无限期挂起。。。这可能与使用SetSocketOption一样简单,但我还不了解该方法的LINQ语法,而且“SocketOption”枚举不是公共的 注意:我正在使用Visual Studio 2013 Express,其
Install Package clrzmq-Version 3.0.0-rc1
用法:启动程序,按“回车”键,告诉主线程关机,然后等待工作人员关机。。。但是主线程将无限期地阻塞
这是我的代码(Program.cs):
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
使用系统线程;
//通过NuGet添加ZeroMQ,如下所示:安装软件包clrzmq-Version3.0.0-rc1
使用ZeroMQ;
使用ZeroMQ.Devices;//排队
名称空间MTSERVICES
{
类线程上下文
{
公共ZmqContext_ZmqContext=null;
public int_threadID=0;
}
班级计划
{
公共静态bool g_keepRunning=false;
公共静态void Main(字符串[]args)
{
WriteLine(“启动MTServiceCS-多线程hello world-启动HelloWorld客户端以测试此服务器”);
使用(var context=ZmqContext.Create())
{
使用(var queue=new ZeroMQ.Devices.QueueDevice)(上下文,“tcp://*:5555”inproc://workers,DeviceMode.Threaded)
{
WriteLine(“初始化队列”);
queue.Initialize();
//TODO:如何将“延迟”设置为零?
//queue.BackendSetup.SetSocketOption(,0);
//queue.FrontendSetup.SetSocketOption(,0);
WriteLine(“创建线程”);
var workerThreads=新线程[5];
//设置为“false”以通知工人关闭
g_keepRunning=真;
对于(int-threadID=0;threadID0)
{
Console.WriteLine(“收到的消息:“+tc.\U threadID.ToString()+”:“+Message”);
Thread.Sleep(1000);//在这里模拟我们的工作,睡眠1秒
//Send(“World”,Encoding.Unicode);
receiver.Send(“World[”+tc.\u threadID.ToString()+“]”,Encoding.Unico
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
// add ZeroMQ via NuGet like this: Install-Package clrzmq -Version 3.0.0-rc1
using ZeroMQ;
using ZeroMQ.Devices; // for queuing
namespace MTServiceCS
{
class ThreadContext
{
public ZmqContext _zmqContext = null;
public int _threadID = 0;
}
class Program
{
public static bool g_keepRunning = false;
public static void Main(string[] args)
{
Console.WriteLine("Starting MTServiceCS - multi-threaded hello-world - start the HelloWorld clients to test this server.");
using (var context = ZmqContext.Create())
{
using (var queue = new ZeroMQ.Devices.QueueDevice(context, "tcp://*:5555", "inproc://workers", DeviceMode.Threaded))
{
Console.WriteLine("Initializing Queue.");
queue.Initialize();
// TODO: how to set the "Linger" to zero?
// queue.BackendSetup.SetSocketOption(, 0);
// queue.FrontendSetup.SetSocketOption(, 0);
Console.WriteLine("Creating Threads.");
var workerThreads = new Thread[5];
// set to 'false' to tell the workers to shutdown
g_keepRunning = true;
for (int threadID = 0; threadID < workerThreads.Length; threadID++)
{
workerThreads[threadID] = new Thread(WorkerRoutine);
// passing in more than just the ZMQ Context
ThreadContext tc = new ThreadContext();
tc._threadID = threadID;
tc._zmqContext = context;
workerThreads[threadID].Start(tc);
}
Console.WriteLine("Threads created.");
Console.WriteLine("Starting Queue.");
queue.Start();
// we block here in the calling thread until "ENTER" is pressed and then try to shutdown...
Console.WriteLine("Press ENTER to shutdown.");
Console.ReadLine();
// tell the workers to exit, sleep and then exit... or die trying...
Console.WriteLine("Setting 'g_keepRunning' to false to tell workers to shutdown.");
g_keepRunning = false;
Console.WriteLine("HACK: Sleeping for 4 seconds to allow workers to exit");
Thread.Sleep(4000);
Console.WriteLine("Queue finished.");
queue.Stop();
Console.WriteLine("Stopping queue...");
if (queue.IsRunning)
{
Console.WriteLine("Queue is NOT running.");
}
else
{
while (queue.IsRunning)
{
Console.WriteLine("Queue is STILL running? Looping waiting for it to close...");
Thread.Sleep(1000);
}
Console.WriteLine("Queue has stopped running!");
}
Console.WriteLine("Queue stopped.");
queue.Close();
Console.WriteLine("Queue closed.");
}
Console.WriteLine("QueueDevice closed.");
Console.WriteLine("Exiting context...");
}
Console.WriteLine("Press ENTER to exit.");
Console.ReadLine();
} // Main
private static void WorkerRoutine(object threadContext)
{
ThreadContext tc = (ThreadContext)threadContext;
ZmqSocket receiver = tc._zmqContext.CreateSocket(SocketType.REP);
// ZmqSocket receiver = ((ZmqContext)threadContext).CreateSocket(SocketType.REP);
receiver.Connect("inproc://workers");
Console.WriteLine("Thread# " + tc._threadID.ToString() + " starting.");
// Console.WriteLine("Thread# starting.");
// 1-second timeout
TimeSpan tsTimeout = new TimeSpan(0, 0, 1);
while (g_keepRunning)
{
string message = receiver.Receive(Encoding.Unicode, tsTimeout);
if (message != null && message.Length > 0)
{
Console.WriteLine("Message received: " + tc._threadID.ToString() + ": " + message);
Thread.Sleep(1000); // simulate our work here w/ a sleep for 1 second
// receiver.Send("World", Encoding.Unicode);
receiver.Send("World[" + tc._threadID.ToString() + "]", Encoding.Unicode);
// Console.WriteLine("Thread# " + tc._threadID.ToString() + " sending.");
}
else
{
Console.WriteLine("No message received: " + tc._threadID.ToString());
}
}
Console.WriteLine("Thread# " + tc._threadID.ToString() + " exiting.");
}
}
}