2016-11-29 73 views
2

我有一份我希望并行执行的任务列表,但以有限的方式执行,几乎就像没有我必须管理的批处理一样。我的方法是使用Parallel.ForEach和ParallelOptions的MaxDegreeOfParallelism属性。我发现无论我设定什么价值,所有任务都是在同一时间开始的。这是不受欢迎的行为。我希望同时执行的任务数量等于该属性。我写了说明MaxDegreeOfParallelism不适用于任务列表?

class Program 
{ 
    static void Main(string[] args) 
    { 
     var numbers = Enumerable.Range(1, 5); 
     var tasks = new List<Task>(); 

     foreach (int number in numbers) 
     { 
      tasks.Add(new Task(() => {Console.WriteLine("Starting thread {0} at time {1}. Starting delay...", Thread.CurrentThread.ManagedThreadId, DateTime.Now); 
      Thread.Sleep(1000); 
      Console.WriteLine("{0} is done at {1}.", Thread.CurrentThread.ManagedThreadId, DateTime.Now);})); 
     } 

     Parallel.ForEach(tasks, new ParallelOptions() { MaxDegreeOfParallelism = 2 }, t => 
     { 
      t.Start(); 
     }); 

     Task.WaitAll(tasks.ToArray()); 
    } 
} 

一个简单的例子,以下是输出: Console Output

是我的方法或理解不正确的?

+0

阅读文档和其他一些问题后 - 我分享你的理解,它应该工作。我希望有人知道答案,这个问题会让我困扰一段时间。 – zmbq

+0

Hi Seapoe,MaxDegreeOfParallelism会影响可以并发运行的线程数。它不确定每个线程何时启动。 – Riv

回答

4

我认为你有点困惑,最大程度的平行性应用于并行ForEach所使用的任务数量,但是在你创建新任务的内部,这些任务不是由ParallelOptions控制,而是由TaskScheduler 。

如果要限制并发任务的数量,您必须创建自定义TaskScheduler并限制运行的任务数。

Here你可以找到一个例子。

+0

有趣。所以在我的例子中,如果我删除了新任务的创建并将执行的代码放入并行循环中,那么是否能够实现我所寻找的目标? – Seapoe

+0

是的,它应该。 – Gusman

+0

是的,工作!非常感谢你!我也会看看自定义调度程序。 – Seapoe