我如何只生成一定数量的线程或任务,然后等待,随着每个线程或任务的完成,在C#中生成一个新线程或任务



我正在创建一个数据清理应用程序,该应用程序在数据库中的表中循环,并清理不同列中的NPI数据。我为每个表创建了一个类,该类具有执行清理操作的方法。我想做的是在表类上循环,并使用反射调用每个类及其清理方法。我想一次做10个表,当一个表完成时,在列表中的下一个表上生成一个新的线程/任务。

我有一个树视图,用户可以从数据库中选择一个或多个表进行清理。我已经能够在选定的表上循环,并在其自己的线程上为每个表调用clean方法,但我最终会有100多个线程(如果所有表都被选中)同时执行。情况并不理想。

有什么建议吗?我使用的是C#和.NET 4.6,所以任务代码是首选。

一种简单的方法是使用Parallel.ForEach,并将MaxDegreeOfParallelism选项设置为您想要的最大线程数。

针对这类问题的一个更高级、更优雅的框架是数据流任务并行库(TPL)。使用ActionBlock来执行工作,并根据需要设置它的并行度。

看看任务并行库,它有一个类型Task和Task,我认为它可以很好地适应您。

你可以创建10个任务,把它们放在一个集合中,然后做一个Tasks.WhenAny(myTasks).Result。这时你可以计算出完成了多少任务,并把更多的任务放在集合中(IsCompleted属性)。

而不是。WhenAny你可能会让它变得不那么复杂,并使用WhenAll(myTasks),然后一批一批地完成这一切。并行foreach答案也是一个很好的选择,TPL中有一个完整的世界供你探索。

非常基本的例子,不确定你在这里的全部上下文:

var myTasks = new List<Task>();
myTasks.Add(Task.Run(() => someLongProcess))
myTasks.Add(Task.Run(() => someLongProcess))
Task.WhenAny(myTasks).Result
//Check to see how many tasks are done, and then add more to your collection and repeat until you're done

您最好使用Task,因为它在内部实现了工作共享:这基本上意味着Task=Work,它通过特殊的任务调度器映射到操作系统的硬件线程上。

  • 线程可能并不总是可用
  • 可能有比线程更多的工作要做,所以如果您有一个队列要处理,那么同一个线程将用于处理新数据(生成线程有其自身的成本)
  • 可能成功的错误共享管理(在CPU缓存线上)。你可能不那么担心,但仍然值得知道它是什么
  • 。。更多

很多可能是的想法,由线程调度程序调度和处理,以在没有太多干扰的情况下获得最佳的通用性能。需要明确的是,你不会得到尽可能好的多线程性能,但你很可能也不需要。

您所问的是数据并行性。

如何使用它的简单示例可以在:如何:编写一个简单的并行程序。对于循环

最新更新