0

我需要在 c# 中并行处理数据库中的几行(可能是数百万行)。处理速度非常快(50 或 150 毫秒/行),但我无法在运行前知道这个速度,因为它取决于硬件/网络。

ThreadPool 或更新的 TaskParallelLibrary 似乎满足了我的需求,因为我是线程新手,并且希望获得最有效的数据处理方式。

然而,这些方法并没有提供一种方法来控制我的任务的执行速度(行/分钟):我希望能够为处理设置最大速度限制或全速运行。

请注意,设置 ThreadPool/TaskFactory 的线程数并不能满足我的需要,因为我希望能够将速度限制设置为低于“单线程速度”。

为 TPL 使用自定义调度程序似乎是一种方法,但我没有找到实现它的方法。

此外,我担心采用这种设置的效率成本。

您能否为我提供如何完成这项工作的方法或建议?

提前感谢您的回答。

4

2 回答 2

1

TPL 在线程池之上提供了一个方便的编程抽象。如果可以的话,我总是会选择 TPL。

如果您希望限制总处理速度,则没有任何内置支持。

您可以在处理文件时测量总处理速度,并通过在每个线程中引入(非旋转)延迟来调节速度。延迟的大小可以根据观察到的处理速度在您的代码中动态调整。

于 2012-12-11T21:10:25.173 回答
0

我没有看到限制速度的优势,但我建议您考虑限制操作的最大并行度。这可以通过ParalleForEach选项属性中的 MaxDegreeOfParallelism 来完成,因为代码在不同的数据行上工作。这样您就可以控制插槽,因为没有更好的术语,可以根据您正在工作的标准来扩展或减少。

这是一个使用ConcurrentBag处理分散数据行并使用 2 个并行任务的示例。

   var myLines = new List<string> { "Alpha", "Beta", "Gamma", "Omega" };

   var stringResult = new ConcurrentBag<string>();

   ParallelOptions parallelOptions = new ParallelOptions();

   parallelOptions.MaxDegreeOfParallelism = 2;

   Parallel.ForEach( myLines, parallelOptions, line =>
   {
      if (line.Contains( "e" ))
         stringResult.Add( line );

   } );

   Console.WriteLine( string.Join( " | ", stringResult ) );
   // Outputs Beta | Omega

请注意,并行选项还具有TaskScheduler属性,您可以优化更多处理。最后为了获得更多控制权,也许您想在达到特定阈值时取消处理?如果是这样,请查看CancellationToken属性以提前退出该过程。

于 2012-12-11T21:42:21.303 回答