在.NET中为线程池保持队列的最佳项目数?

在.NET中为线程池保持队列的最佳项目数?,.net,threadpool,workload,.net,Threadpool,Workload,我正在构建一个后台处理引擎,它支持丢弃待处理和正在处理的项目。这是在winforms应用程序中使用的,该应用程序需要大量处理一些输入元素,因此我正在构建一个队列引擎,在这里我可以将工作负载项排队,当它们被处理时,我会收到结果通知 问题是,这个队列几乎总是包含很多要开始的项目,我想我不会将所有内容都转储到线程池,而是只将前N个项目放入线程池,并在处理它们时继续回填。我这样做的原因是,一旦我将它们转储到threadpool中,它们就会被处理,即使它们被标记为discard,它们仍然会占用队列时间 使

我正在构建一个后台处理引擎,它支持丢弃待处理和正在处理的项目。这是在winforms应用程序中使用的,该应用程序需要大量处理一些输入元素,因此我正在构建一个队列引擎,在这里我可以将工作负载项排队,当它们被处理时,我会收到结果通知

问题是,这个队列几乎总是包含很多要开始的项目,我想我不会将所有内容都转储到线程池,而是只将前N个项目放入线程池,并在处理它们时继续回填。我这样做的原因是,一旦我将它们转储到threadpool中,它们就会被处理,即使它们被标记为discard,它们仍然会占用队列时间

使用我所做的回填实现,如果项目被丢弃,我可以将其从队列中移除,并且只能在轮到它们的时候将它们放入队列中

所以问题是,我将如何计算这个数字N,线程池队列中要放入和保留的项目数

我考虑过的问题:

  • 我可能希望将2*个处理器排成一列,我看到这是一个典型的项目数,以确保所有处理器都正常工作
  • 但是,如果某些项目的实际处理速度非常快(可能发生这种情况),那么线程池中的队列在我自己的类可以用更多的工作进行回填之前就已经耗尽了,所以我可能希望使用更大的数量,以避免处理器利用不足
  • 我是否应该创建一些自动调整例程,根据每个项目所花费的当前时间来计算最佳数量,这样,如果它们都非常快,那么数量会高得多,如果处理需要一点时间,那么数量应该保持在较低的水平
你觉得怎么样

新的:好的,根据其中一个答案,我将进一步解释。放入队列中的每一项都由唯一的内容键入。如果我使用与现有项相同的密钥将另一项转储到队列中,则该旧项将被视为“已丢弃”,并应被删除。如果正在处理该项,则工作负载项上的属性设置为true,即处理方法负责调用的“IsDicarded”属性。如果它检测到一个被丢弃的项目,它应该提前退出,不返回任何结果

也许我应该多做一点实验,试着把所有东西都转储到线程池中

新问题:我可以排队的项目数量有限制吗?如果没有,那么这将很容易简化我的类很多


注意:当我说“长时间处理”时,我的意思是1-10秒。线程池是最好的吗?我在网上看到了很多关于“处理应该是快速的”的注释,但什么是“快速”却从未被提及。这里的速度是以毫秒为单位的吗?

您是否可以通过修改项目来简化方法,首先检查它们是否仍然是必需的,然后再执行任何工作?这将避免限制池中的数量的问题,因为您可以简单地将它们全部添加,并且当处理每个项目时,如果不再需要,它将退出

可以执行的操作数 排队到线程池的线程数量有限 只有可用内存;但是, 线程池限制线程的数量 可以在中处于活动状态的线程 同时处理。默认情况下, 限制为每个线程250个工作线程 CPU和1000个I/O完成线程

您可以控制最大数量的 通过使用GetMaxThreads和 SetMaxThreads方法

你知道Ami酒吧吗


它的实现似乎允许您取消未处理的项目,并根据需要动态增加线程,直到达到硬限制;我个人使用的是
100*Environment.ProcessorsCount

是的,他们这样做了,发送到委托中的项目包含一个“IsDicarded”方法,他们需要调用该方法,不仅是在处理之前,而且在处理过程中,如果处理很长,也需要提前中止。这可能是因为我把事情复杂化了,应该只跟踪现有的项目,它们被设置了密钥,这样我就可以找到它们,在替换时丢弃它们,然后将它们全部转储到线程池中。也许我应该尝试一下这个解决方案。听起来确实值得一试,特别是如果这意味着避免手动调整和管理线程池的其他复杂性。你知道我可以放入线程池的工作项的数量是否有限制吗?这看起来是进行一些实验的最佳时机:)啊,看起来我需要看看鲁本斯提到的智能线程池,我需要优先排序支持。例如,当打开所讨论的表单时,所有数据都排队等待处理,但如果用户更改网格中的某些特定列,则这些列的结果将以更高的优先级重新排队等待处理,因此最终所有数据都将被处理,但用户处理的任何数据都将首先被处理。否,我不知道那件事,我会调查的,看起来很有希望。最好的代码是我不必编写的代码,但它只是开箱即用:)