0

我开始一个小小的“工作管理器”,它会执行一个“Job”对象实现一个“IJob”方法。每个IJob都会返回潜在的新工作列表。使用TPL做一些“工作”

我所有的工作都存储在一个队列中,这个队列可以安全地访问线程,当我完成一个工作时,我将这个队列添加到新的查询作业中。

我正在寻找如何将此与TPL并行化。

我有一些想法,但他们都不是有效的,由于我的限制,这是:

  • 我需要限制线程的数量(假设4),因为有些要求是quering一个网站,它不允许超过4个同时请求(我想我可以用信号量来管理这个)
  • 我的工作列表将会改变,所以我不能启动4个线程,将工作数量除以数字的线程,并且每个线程都运行他的一堆工作。
  • 也许有时候,如果我有4个线程,我只有一个工作更多,但我不能让其他线程停下来,因为也许我上次运行的工作会创造更多的工作。

非常感谢!

回答

0

这真是动态的任务并行。您的代码循环遍历您拥有的任务并执行每个任务。每个作业都可以向使用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

0

您可以简单地使用ParallelOptions.MaxDegreeOfParallelism来限制同时执行多少个并发任务。

Reed Copsey在他的博客上有an example

+0

呀的例子,但我仍然有我的主要问题,这并不为集合其变化工作。他们总是做一个 collection.AsParallel(),但是这将不会考虑我添加到集合中的所有新作业: – J4N 2011-04-15 20:47:10

0

查看Campbell,Johnson,Miller和Toub的Microsoft .NET的并行编程...具体来说,第3章的“带线程本地工作队列的全局队列,通过TPL,采用工作窃取算法”来处理负载平衡。

我用它作为我设计的基础之一,它确实在性能上有很大的不同。

+0

是的,但是我的问题并不是真正的“负载平衡”,它更多我不'当我要求开始这项工作时,我没有完成所有的任务,但当我只有一份工作时,负载平衡不会有什么帮助,而这份工作将会产生很多未来的工作,4项工作中的3项将停止: / – J4N 2011-04-20 09:05:39