c#任务多队列限制

时间:2012-03-25 01:44:28

标签: c# queue task-parallel-library task

我需要一个需要维护不同任务队列的环境,并且每个队列都有一个可以为每个队列执行的明确定义数量的并发线程。像这样:

  • 队列1 - > 3个线程;
  • 队列2 - > 6个线程;

种类的任务系统。我已经设法自己实现了这个使用普通的旧c#代码(又名System.Threading.Thread,lock和queue),它可以工作超过1年。但是,我一直在阅读有关TaskFactory和TaskScheduler奇迹的文章,关于.NET中内置类的可能性,但我没有找到证明这一点的例子。我想测试它,并与我现在所做的比较,看看它是否工作得更好,如果有的话,更换它。

更多,我可以在不必限制/设置每个队列的并行线程数的情况下生存,只要我能得到guarantee即使队列#2的目标也是imediatly,即使队列# 1正在满载时执行。

所以,我的问题是 - 是否有.net 4及更多内容,是否有人能指出我的样本?我整整一周都在寻找一个并没有得到相关的东西。

2 个答案:

答案 0 :(得分:8)

使用TPLSystem.Collections.Concurrent中的新集合,这实际上非常简单。

根据您的需要,我会推荐BlockingCollection<T>。默认情况下,它使用ConcurrentQueue<T>作为底层商店,非常适合您想要的商品。

var queue = new BlockingCollection<Message>();

设置一些处理这些消息的代码,并控制并行执行的代码数量就像这样简单:

//Set max parallel Tasks
var options = new ParallelOptions
{
    MaxDegreeOfParallelism = 10
};

Parallel.ForEach(queue.GetConsumingEnumerable(), options, msg =>
{
    //Do some stuff with this message
});

那么这里发生了什么?嗯......

GetConsumingEnumerable()的调用实际上会阻止,直到queue中的内容消耗完为止。这很好,因为没有必要使用额外的代码来表明新工作已经准备就绪。相反,当queue填满时,您的(匿名)委托的新任务将会以项目启动。

ParallelOptions对象可让您控制Parallel.ForEach的运作方式。在这种情况下,您告诉它您永远不会希望一次执行超过10个任务。 重要的是要注意Tasks!= Threads 。细节是模糊不清的,但不用说,引擎盖下有很多优化。对你来说,这一切都是可以插入的,但这不适合胆小的人。

显然我在这里没有涉及很多细节,但希望你能看到使用任务并行库有多么简单和富有表现力。

答案 1 :(得分:3)

您可以尝试创建this example中提到的LimitedConcurrencyLevelTask​​Scheduler的等效项,或者查看提到的here优先级调度程序。