【问题标题】:Guarantee immediate start of parallel threads/tasks/whatever保证立即启动并行线程/任务/其他
【发布时间】:2016-09-06 23:15:15
【问题描述】:

我将使用“进程”来指代将要并行发生的工作,而“入队”来指代将用于启动该进程的任何进程(无论是 Task.Run、ThreadPool. QUWI,new Thread() ... 随便)。

我们有一个性能敏感的程序,它产生多个并行进程来收集数据。

我们在生成过程中遇到问题,进程没有立即开始。

具体来说,如果我们准备一个进程,启动一个计时器,将进程排入队列,并将计时器作为进程中的第一个动作进行检查……那么我们会看到时间延迟偶尔会延长到 100 秒甚至 1000 毫秒.

鉴于进程本身应该只运行 3-10 秒,因此在进程入队和激活之间有 2 秒的延迟是一个主要问题。

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

目前我们的实现开始使用 TP.QUWI,然后我们转向使用 Task.Run。 我们最初的调查将我们引导到 Threadpool 使用的 Thread-Creation-Strategy 并使用 ThreadPool.SetMinThreads(),因此我们正在追求这个角度,看看这是否能彻底解决问题。

但是,如果我们的目标是让流程在入队后立即开始,是否还有其他我们应该关注的变化/方法?

【问题讨论】:

  • 您的应用程序是否将ThreadPool 广泛用于其他对时间不敏感的“进程”?为什么时机对你来说如此重要?
  • 我不明白这些问题,@svick?是的,我们还将ThreadPool 用于一些不在性能关键路径中的后台任务,但我看不到相关性。就像我说的那样......该程序对性能很敏感......我不明白为什么这样做的原因很重要?

标签: c# multithreading parallel-processing task-parallel-library threadpool


【解决方案1】:

Taken from here(我强烈建议你阅读一下):

似乎可以通过覆盖默认任务调度程序来实现您想要的......吓人......

您不能假设所有并行任务都会立即运行。根据当前的工作负载和系统配置,任务可能被安排为一个接一个地运行,或者它们可能同时运行。有关如何计划任务的更多信息,请参阅本章后面的“默认任务计划程序”部分。

使用自定义计划创建任务

您可以通过覆盖任务工厂方法使用的默认任务计划程序来自定义如何计划和运行 .NET 中的任务的详细信息。例如,您可以将自定义任务调度程序作为参数提供给 TaskFactory.StartNew 方法的重载版本之一。

在某些情况下,您可能想要覆盖默认调度程序。最常见的情况发生在您希望任务在特定线程上下文中运行时......其他情况发生在默认任务调度程序的负载平衡启发式方法不适用于您的应用程序时。有关详细信息,请参阅本章后面的“线程注入”部分。

除非您另外指定,否则任何新任务都将使用当前任务调度程序...

您可以实现自己的任务调度程序类。有关详细信息,请参阅本章后面的“编写自定义任务计划程序”部分。

线程注入

.NET 线程池自动管理池中工作线程的数量...

阅读this SO post "replacing the task scheduler in c sharp with a custom built one"

【讨论】:

  • 与仅显式启动线程相比,我认为这种相当复杂的方法几乎没有什么好处:在谈论 10 秒的工作时,线程创建的开销可以忽略不计,如果它想要自定义解决方案,那将不是微不足道的重用线程。任务接口很有用,但一个小包装器仍然可以将工作公开为任务。
猜你喜欢
  • 1970-01-01
  • 2021-01-08
  • 2023-02-24
  • 1970-01-01
  • 2011-11-27
  • 1970-01-01
  • 2013-12-16
  • 1970-01-01
相关资源
最近更新 更多