Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 始终运行10个TPL任务的好方法&;在循环中完成后启动一个新的?_.net_C# 4.0_Parallel Processing_Task Parallel Library - Fatal编程技术网

.net 始终运行10个TPL任务的好方法&;在循环中完成后启动一个新的?

.net 始终运行10个TPL任务的好方法&;在循环中完成后启动一个新的?,.net,c#-4.0,parallel-processing,task-parallel-library,.net,C# 4.0,Parallel Processing,Task Parallel Library,我有一个Winform应用程序,我正在学习并行编程的TPL。WinForm正在连续运行&一次浏览10个网站。每个网站都由TPL任务处理。这些任务相互独立。每完成一项任务,就会启动一项新任务。我打算使用Task.Factory.StartNew(..)来启动任务 我熟悉启动第三方物流任务,但我不知道如何在一个循环中同时启动多个第三方物流任务,并在每次完成时启动一个新的第三方物流任务,有效地让10个任务始终运行 如何执行此操作?使用您自己的TaskFactory计划程序 然后基本上通过该调度程序分

我有一个Winform应用程序,我正在学习并行编程的TPL。WinForm正在连续运行&一次浏览10个网站。每个网站都由TPL任务处理。这些任务相互独立。每完成一项任务,就会启动一项新任务。我打算使用Task.Factory.StartNew(..)来启动任务

我熟悉启动第三方物流任务,但我不知道如何在一个循环中同时启动多个第三方物流任务,并在每次完成时启动一个新的第三方物流任务,有效地让10个任务始终运行


如何执行此操作?

使用您自己的TaskFactory计划程序


然后基本上通过该调度程序分配10个线程。

如果您有一个包含1000个URL的列表,但您希望同时处理的URL不超过10个,最简单的方法是使用10个,如下所示:

Parallel.ForEach(myListOfUrls,
    new ParallelOptions
    {
        MaxDegreeOfParallelism = 10
    },
    url =>
    {
        // processing here
    });

这是真正的动态任务并行。您的代码在您拥有的URL中循环,并在每个URL上执行正文。它还使用addMethod和并发队列将任何新URL添加到队列中

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;
  }
}
publicstaticvoidparallellwhilenotempty(
IEnumerable初始值,
行动机构)
{
var opts=新的并行选项{MaxDegreeOfParallelism=10};
var from=新的ConcurrentQueue(初始值);
而(!from.IsEmpty)
{ 
var to=新的ConcurrentQueue();
Action addMethod=to.Enqueue;
Parallel.ForEach(from,opts.body(v,addMethod));
从=到;
}
}
这样,“循环”是开放式的,将一直持续到您的工作结束。很明显,你真正的应用程序会考虑重复的URL,而不会添加它们等。但这允许你的应用程序动态添加工作。您可以使用ParallelOptions来限制并发性,也可以编写调度程序

有关动态任务并行性的更多信息,请参阅

有关示例的完整代码,请参见

以上两个都讨论了这个主题的其他变体

如果希望自定义调度程序限制并行度,请参见MSDN上的示例


如果一开始就有固定数量的URL,那么这很好。然而,对于一个网络蜘蛛来说,你将把一些东西添加到列表中。不同的问题需要解决。如果是这种情况,您将切换到生产者/消费者模式,myListOfUrls将只是一个BlockingCollection,您将在另一个任务上生成Parallel::ForEach off,您可以一直添加到它,直到完成,然后调用CompleteAdding。或者切换到使用TPL数据流(这就是我要做的),并一直发布到目标块,直到完成为止。有很多选择。