C# 具有速度执行控制的线程池

C# 具有速度执行控制的线程池,c#,task-parallel-library,threadpool,C#,Task Parallel Library,Threadpool,我需要在c#中并行处理数据库中的几行(可能是数百万行)。处理速度相当快(50或150ms/行),但在运行前我无法知道这个速度,因为它取决于硬件/网络 ThreadPool或更新的TaskParallelLibrary似乎正是我所需要的,因为我是线程新手,希望获得最有效的数据处理方式 但是,这些方法没有提供控制任务执行速度的方法(行/分钟):我希望能够为处理设置最大速度限制或全速运行 请注意,设置ThreadPool/TaskFactory的线程数并不能满足我的需要,因为我希望能够将速度限制设置为

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

ThreadPool或更新的TaskParallelLibrary似乎正是我所需要的,因为我是线程新手,希望获得最有效的数据处理方式

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

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

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

此外,我担心这样的设置会带来效率成本

你能给我一个方法或建议如何实现这项工作


提前感谢您的回答。

TPL在线程池之上提供了一个方便的编程抽象。我总是会选择第三方物流,当这是一个选项

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


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

我看不出限制速度的好处,但我建议您考虑限制操作的最大视差。当代码在不同的数据行上工作时,可以通过ParalleForEach options属性中的。这样,您可以控制插槽,因为没有更好的术语,可以根据您工作的标准扩展或减少这些术语

下面是一个使用来处理分散数据行和使用两个并行任务的示例

   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
var myLines=新列表{“Alpha”、“Beta”、“Gamma”、“Omega”};
var stringResult=新的ConcurrentBag();
ParallelOptions ParallelOptions=新的ParallelOptions();
parallelOptions.MaxDegreeOfParallelism=2;
ForEach(myline,parallelOptions,line=>
{
如果(第行包含(“e”))
stringResult.Add(行);
} );
Console.WriteLine(string.Join(“|”,stringResult));
//输出β|ω

请注意,并行选项还有一个属性,您可以对其进行更多的处理。最后,为了更好地控制,当达到特定阈值时,您是否希望取消处理?如果是这样,请查看属性以尽早退出流程。

感谢您的快速回答,您能解释什么是非阻塞延迟吗?您建议观察活动线程的数量并调整延迟,还是设置固定数量的线程以防止额外的计算?非阻塞延迟可以像thread.Sleep(NumberOf毫秒)一样简单。如果工作负载很大程度上受CPU限制,我会让一个线程读取数据并将其写入
BlockingCollection
,然后使用N个线程处理
BlockingCollection
中的项目。我最初会将N设置为CPU内核的数量,并测量性能。一旦为您的用例确定了最佳线程数,我将通过延迟线程而不是添加或删除线程来调整吞吐量。@EricJ.:Thread.Sleep何时为“非阻塞”?发送到睡眠状态的线程被阻止,其他所有线程都被阻止。你是那个意思吗?@igrimpe:谢谢你指出这一点。我的意思是不旋转(编辑答案)。非阻塞会更好,因为线程甚至不会被调度(也不会占用线程池插槽),但除非使用新的异步/等待机制,否则该线程的编程会稍微复杂一些。看看任务。延迟非阻塞睡眠需求为什么要限制速度?你想做什么样的处理?您是否保持连接打开(颤抖!)?处理数据库记录的最佳位置是数据库本身。正确的SQL语句或存储过程(不使用游标)是处理数据的最有效方法。RDBMS将根据需要并行处理数据。如果需要,大多数RDBMS也有自己的方法来限制资源。请记住,数据仓库和星型模式可以在普通硬件中处理数十亿行事件,并且在decadesI编写电子邮件发送队列时一直如此。我需要控制与邮寄相关的特定需求的速度,这是我打算编写的软件的一个强制性功能。处理主要是CPU使用(模板处理)。基于我希望做的事情的类型,完整的SQL处理不是一个选项。正如我所说的,线程的数量不能提供足够的精度来满足我的需要。然而,ConcurrentBag似乎对我正在尝试做的事情很有趣。实现自定义TaskScheduler似乎是一种干净高效的方法,但我不知道如何实现它,而且web上的自定义TaskScheduler示例数量也不多。