使用TPL进行一些“工作”

| 我正在启动一个\“ job manager \”,它将执行一些\“ Job \”对象实现一个\“ IJob \”方法。每个IJob都会通过返回潜在的新作业列表来完成。 我所有的作业都存储在一个队列中,可以通过线程安全地对其进行访问,当我完成一个作业时,将新查询的作业添加到此队列中。 我正在搜索如何将其与TPL并行化。 我有几个想法,但由于我的限制,这些想法都不成立: 我需要限制线程的数量(比如说限制为4),因为某些请求正在查询一个网站,该网站不允许同时出现4个以上的请求(我想我可以使用信号量来管理它) 我的作业列表将更改,因此我无法启动4个线程,将作业数除以线程数,然后每个线程都会运行其作业堆栈。 也许有时候,如果我有4个线程,我只会再执行一个作业,但是我不能停止其他线程,因为也许我要运行的最后一个作业会创建更多的作业。 非常感谢你!     
已邀请:
这实际上是动态的任务并行性。您的代码循环遍历您拥有的作业并执行每个作业。每个作业都可以使用addMethod和并发队列将新作业添加到中。
public static void ParallelWhileNotEmpty<T>(
  IEnumerable<T> initialValues, 
  Action<T, Action<T>> body)
{
  var opts = new ParallelOptions { MaxDegreeOfParallelism = 10 };
  var from = new ConcurrentQueue<T>(initialValues);  
  while (!from.IsEmpty)
  { 
    var to = new ConcurrentQueue<T>();
    Action<T> addMethod = to.Enqueue; 
    Parallel.ForEach(from, opts. body(v, addMethod));        
    from = to;
  }
}
这样,“循环”是开放式的,将一直持续到您用尽工作。显然,您的实际应用程序会考虑重复的URL,而不添加它们,等等。但这使您的应用程序可以动态添加工作。您可以使用ParallelOptions限制并发性,也可以编写调度程序。 有关动态任务并行性的更多信息,请参见 http://msdn.microsoft.com/en-us/library/ff963551.aspx 有关示例的完整代码,请参见 http://parallelpatterns.codeplex.com/SourceControl/changeset/view/54510#795590 以上两个都讨论了有关此主题的其他替代变体。 如果要自定义调度程序限制并行度,请参见MSDN上的示例 http://msdn.microsoft.com/en-us/library/ee789351.aspx     
您可以简单地使用ParallelOptions.MaxDegreeOfParallelism来限制同时执行多少个并发任务。 里德·科普西(Reed Copsey)在他的博客中有一个例子。     
查阅Campbell,Johnson,Miller和Toub撰写的使用Microsoft .NET进行并行编程...特别是第3章的“通过TPL使用线程本地工人队列的全局队列,该队列使用工作窃取算法”来处理负载均衡。 我以此为基础进行设计,这确实对性能产生了巨大影响。     

要回复问题请先登录注册