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

时间:2016-03-28 20:56:43

标签: c# sql-server multithreading

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

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

有关如何执行此操作的任何建议?我正在使用C#和.NET 4.6,因此首选任务代码。

3 个答案:

答案 0 :(得分:4)

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

Dataflow Task Parallel Library(TPL)是针对此类问题的更高级且相当优雅的框架。使用ActionBlock执行工作并根据需要设置它的并行度。

答案 1 :(得分:0)

最好使用Task,因为它在Work sharing内实现:这基本上意味着Task=Work,它通过特殊Task Scheduler映射到操作系统的硬件线程上。

  • 线程可能无法始终可用
  • 可能还有比线程更多的工作,所以如果你有一个要处理的队列,那么同一个线程将用于处理新数据(产生一个线程有自己的成本)。
  • 可能成功的虚假共享管理(在CPU缓存行上)。你可能不太关心,但仍然值得知道它是什么。
  • ..更多。

很多可能由线程调度程序思考,调度和处理,以获得最佳的通用性能,而不需要太多的喧嚣。要清楚,你不会得到最好的多线程性能,但你很可能也不需要它。

您要问的是数据并行。

如何使用它的简单示例,您可以在How to: Write a Simple Parallel.For Loop

中找到

答案 2 :(得分:0)

看看任务并行库,它有一个类型的任务和任务,我认为它会很好地适合你。

您可以创建10个任务,将它们放入集合中并执行Tasks.WhenAny(myTasks).Result。此时,您可以确定完成了多少任务并将更多内容放入集合中(IsCompleted属性)。

而不是.WhenAny你可能会使它变得不那么复杂并且使用WhenAll(myTasks),并且只需要批量执行x。平行的foreach答案也是一个很好的选择,TPL中有一个完整的世界供您探索。

非常基本的例子,不确定你的完整背景:

find . -type f -ls | sort -r -n -k7 | head -n 1 -printf %s
相关问题