以编程方式限制在服务内运行的线程的CPU使用率

我正在使用VB9(VS2008)。

我已经创建了一个定期为某些文件夹编制索引的Windows服务。

有没有办法可以根据当前系统状态对CPU使用率设置上限,即,如果系统处于空闲状态,则线程可以根据需要使用CPU,但是如果有其他程序/进程正在运行那么它应该以不会使系统变慢的方式使用CPU。

您可以通过Thread.Priority在.Net中降低线程的优先级

将其设置为BelowNormal将意味着将在其前面安排其他线程。

这可能导致线程缺乏,但听起来这是一个可接受的设计决定,以满足您的需求。

请注意,由于您正在执行相当大的磁盘IO,这实际上将是后台任务的主要影响,您可能会发现降低优先级是不够的(因为即使在线程受到限制时,磁盘IO也会继续部分继续。

检查机器使用情况的监控线程(可选择仅在至少一个交互式用户存在时才关注)可以暂停索引(或大大限制IO)。 这对于有许多可用内核(和超线程虚拟内核)的现代机器来说更为重要,这意味着尽管用户实际上做了大量工作,但是存在备用资源来执行索引线程而不是真正执行磁盘IO。

您可能还想考虑是否检查电源方案以确定是否应该在那时运行(因为来自两个重磁盘访问的电池消耗都是不可忽视的)

如果您希望做更多工作来减少此后台的影响,那么从Vista开始,IO绑定任务版本的Windows将添加两个有用的API:

低优先级I / O.

这允许您的代码以比其他I / O更低的优先级调度I / O.

Windows任务计划程序

您可以使用它来安排在“系统空闲时间”运行的东西。 这在系统不忙时,用户不在场。

在XP上,ShuggyCoUk是正确的。 首先要做的只是将线程优先级降低到低于8的值。这意味着任何其他运行优先级为8或更高的线程或进程将始终运行而不是您的线程。 注意,我不建议简单地将进程优先级设置为<8,而只是将您想要运行的线程(或多个线程)设置为“很好”。

正如Shuggy指出的那样,问题不在于CPU时间 – 它是您的服务产生的I / O. 在XP上,所有I / O都被视为相同 – 因此您的I / O有可能干扰其他事情。

Vista(很快就在Win7上)有两件事可以完全按照你的意愿去做。

第一个是Windows任务计划程序 。 您可以使用它来安排在“系统空闲时间”运行的东西。 这在系统不忙时,用户不在场。

第二个是低优先级I / O. 这允许您的代码以比其他I / O更低的优先级调度I / O.

这两者一起可用于开发一个良好的系统公民代码。

请注意,当系统使用电池运行时,您还应通过缩小或禁用后台项目来考虑移动系统。 你可以很简单 – 简单地关闭电池电源; 或者复杂,将Power Scheme考虑在内,并将其作为用户的提示。

既然您正在编写一个优秀的系统公民服务,那么您也可以做其他一些事情。

1)您可以监控一段时间内完成的工作量,如果已经取得足够的进展,则可以减速或停止。 2)注意你的记忆足迹 – 越小越好。 这通常是不言而喻的,但对于服务而言它是特别重要的,因为它们全天候运行。

如果使用SetThreadPriority API,则可以将线程配置为使用低于正常值的线程优先级。 当系统空闲时,线程将使用所有可用的CPU资源,但会将CPU时间放弃到具有更高优先级的任何线程。

您的系统来自索引过程的大部分负担可能是磁盘I / O,因此除了ShuggyCoUk所说的,如果您的过程在Vista / Windows Server 2008中运行,您还可以将磁盘I / O优先级更改为后台。 这就是大多数分页,碎片整理和其他维护任务在这些系统上运行的方式。 如果没有,您还可以监视磁盘I / O队列,以查看是否存在来自用户交互的待处理操作。