我的web服务有一个奇怪的情况。
它是一个简单的线程-它创建一个不断运行的线程,在后台执行一些磁盘检查,并且对于它执行的每个File.Exists,它都进入睡眠(10),所以它不会消耗所有的CPU核心。
在我从RDP登录之前,一切都运行良好。当我这样做的时候,这个线程将达到峰值,并尽可能多地消耗。
给你,看-看...
我有两个核心,我的前台应用程序使用了大约18%的CPU (NOW-meter上显示的是whis)。左边是无人登录时的CPU使用率。
怎么一回事?更多-在这种情况下,如何适当地限制线程?

我的代码片段产生了这个问题:
foreach (string fi in files)
{
if (_shouldStop)
{
break;
}
lock (_workItems)
{
StatusString = string.Format("Examining file Dir={0}\nmask={1}\nfile={2}\nqueue={3}",
root, mask, fi, _workItems.Count);
}
lock (_workItems)
{
if (!_workItems.Contains(fi))
{
if (!File.Exists(TargetForFile(fi + ".hash")))
{
StatusString = string.Format("Adding file Dir={0}\nmask={1}\nfile={2}\nqueue={3}",
root, mask, fi, _workItems.Count);
_workItems.Add(fi);
}
}
}
Thread.Sleep(10);
}小更新:
当代码作为windows服务运行并且没有人连接到机器时,即使是Sleep(1000)也不执行任何操作。我正式宣布它为WTF。
发布于 2011-12-09 08:17:43
10号睡眠时间只有10毫秒--所以你真的快要放弃并回去工作了。
我的猜测是,当你登录时,你的线程不会立即被重新调度,所以它实际上会在超过10毫秒的时间内处于不活动状态(我想我读到的睡眠的最大分辨率是100 mills,顺便说一下)。但是,当您没有使用RDP时,线程可以更频繁地重新调度,因此它会消耗更多的CPU。
要进行测试,请尝试将睡眠持续时间增加到500 (0.5秒)或1000秒左右,以获得明显的睡眠时间。
另一个测试是在不做任何事情的循环中抛出另一个线程,并查看当您强制file.exists繁忙时,您的CPU线程是否有礼貌地让步。
发布于 2011-12-09 08:34:11
别睡了。将您的线程优先级设置为IDLE。
下一件事是确定每个进程的CPU消耗,这样就不会无关紧要了。打开Perfmom.exe并查看Process(*)\(*)对象(所有实例)。然后,您可以检查每个进程的% Processor Time和% User Time,并在RDP关闭时确定谁在使用这18%。
顺便说一句,为什么不使用change notifications mechanism而不是shuffling same directories over and over again呢?
发布于 2011-12-09 08:32:00
当我登录到RDP时就会遇到这样的问题,而且我没有让你的代码运行。奥卡姆的剃刀表明是RDP在利用内核。
此外,如果你正在做File.Exists,线程无论如何都会阻塞磁盘I/O,如果有一个点,它会给CPU带来严重的负担,当它刚刚完成的时候,它不会。
最后,如果您还没有做任何疯狂的事情,比如将进程优先级从正常情况下调高,那么它无论如何都会与其他进程共享内核。如果它陷入了一个紧凑的循环,这可能会有点糟糕,但即使这样,调度器也应该防止它自己造成太大的危害。对于较新版本的Windows,如果您有多个内核,则更是如此。
编辑:实际上,把所有这些都删掉。为什么要自己在循环中轮询,而不是响应FileSystemWatcher事件。设置一个或多个FileSystemWatcher来监视感兴趣的目录,然后轮询您关心的特定文件存在更改。更少的代码工作,也应该更具响应性。
https://stackoverflow.com/questions/8439502
复制相似问题