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

时间:2009-01-27 08:01:31

标签: c# multithreading windows-services service

我正在使用VB9(VS2008)。

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

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

4 个答案:

答案 0 :(得分:17)

您可以通过Thread.Priority

降低.Net中线程的优先级

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

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

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

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

你可能还想考虑是否检查Power Scheme以确定你是否应该在那个时候运行(因为重磁盘访问的电池耗尽是不可忽视的)

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

Low Priority I/O

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

Windows Task Scheduler

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

答案 1 :(得分:3)

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

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

Vista(很快就会在Win7上)有两件事可以完全按照你想要的方式完成。

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

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

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

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

由于您正致力于编写一个优秀的系统公民服务,您也可以做其他一些事情。

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

答案 2 :(得分:1)

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

答案 3 :(得分:1)

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