我有一种情况,我需要有大量(数百个)队列,其中项目应该按顺序处理(需要单线程消费者)。我的第一个实现基于示例,我为每个 BlockingCollection 使用了一个长时间运行的任务来使用队列项。然而,我最终得到了一个有数百个线程的应用程序,这些线程大多处于空闲状态,除了消耗内存之外什么都不做,因为队列大部分时间都是空的。
我认为只有在队列中有要处理的东西时才运行消费者任务会更好,但是,我无法找到提供最佳实践的示例。
我想出了一个类似于下面的解决方案。但问题是,每个项目都会导致一个新任务(也许这效率低下?浪费资源?)。但是,如果我不为每个项目创建一个新任务,我不能保证一个项目不会在未处理的队列中。
private object _processSyncObj = new object();
private volatile bool _isProcessing;
private BlockingCollection<string> _queue = new BlockingCollection<string>();
private void EnqueueItem(string item)
{
_queue.Add(item);
Task.Factory.StartNew(ProcessQueue);
}
private void ProcessQueue()
{
if (_isProcessing)
return;
lock (_processSyncObj)
{
string item;
while (_isProcessing = _queue.TryTake(out item))
{
// process item
}
}
}
什么是这种情况的最佳实践/最佳解决方案,并保证不存在项目在队列中但没有消费者正在运行的情况?