环境
流程
使用异步模式( ReceiveCompleted
事件订阅)接收消息:
private void OnMessageReceived(object source, ReceiveCompletedEventArgs eventArgs) {
var queue = (MessageQueue)source;
Message m = null;
try {
var processor = new Thread(() => {
try {
// 1. process the message
// 2. send a feedback to m's response queue
}
catch(Exception ex) {
Logger.Log.Error(ex);
// 1. send a feedback to m's response queue
}
};
processor.Start();
}
catch(Exception ex) {
Logger.Log.Error(ex);
}
queue.BeginReceive();
}
问题
产生单独的工作线程后,我应该遵循一些限制。
假设我想使用 1-5个工作线程(最大值)来处理消息,如果所有可用的工作人员都忙,那么:
如果所有可用的工作人员都忙 , 部分是否意味着我必须实现类似于线程池的内容?
我在问题中添加了system.reactive。这是由于我看到的一些代码,其中使用了 Rx Buffering 。我不太明白这是否适用于我的情况。在我的情况下,我可以使用 Rx 吗?
答案 0 :(得分:1)
如果您的服务由IIS托管,IIS可能会阻止此操作,但您可以尝试使用ThreadPool
,尤其是使用其SetMaxThreads
方法。请注意,您不能将它们设置为低于当前处理器数量,但限制是应用程序范围的(备注请注意,这可能会对您的应用程序使用的库产生负面影响),并取决于具体情况。主机可能会阻止您以这种方式设置线程。
您可以尝试使用它自己运行,实现private static Queue<Thread> threadPool;
,使用所需数量的线程静态初始化它,并执行以下操作:
var processor = threadPool.Dequeue();
...
// there's no easy thread-safe way to check this in .net 3.5 -
// if you can use concurrent queue you could do this after checking if
// there's anything available in the queue with a ConcurrentQueue<Thread>
//queue.BeginReceive(); // call this from the end of your thread execution now
您的线程可以在Enqueue
队列完成处理后返回threadPool
队列,并在MSMQ BeginReceive()
对象上调用queue
以便进程可以继续(将queue
传递给此处记录的帖子https://msdn.microsoft.com/en-us/library/ts553s52(v=vs.85).aspx)。
如果您对如何在.NET 3.5中实现ConcurrentQueue
感兴趣,可以随时查看Reference Source - 但我个人认为关于升级到最新.NET版本的内容。