Rob*_*iks 4 .net c# multithreading behavior
关于C#中的线程,我有一个小问题.出于某种原因,当我打开Chrome时,我的线程从32ms延迟加速到16ms延迟,当我关闭Chrome时它会回到32ms.我正在使用Thread.Sleep(1000 / 60)延迟.有人可以解释为什么会发生这种情况,并建议一个可能的解决方案吗?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace ConsoleApplication2
{
class Program
{
static bool alive;
static Thread thread;
static DateTime last;
static void Main(string[] args)
{
alive = true;
thread = new Thread(new ThreadStart(Loop));
thread.Start();
Console.ReadKey();
}
static void Loop()
{
last = DateTime.Now;
while (alive)
{
DateTime current = DateTime.Now;
TimeSpan span = current - last;
last = current;
Console.WriteLine("{0}ms", span.Milliseconds);
Thread.Sleep(1000 / 60);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
只是一个帖子来确认马修的正确答案.精度Thread.Sleep()受Windows上时钟中断率的影响.它默认为每秒64次,每15.625毫秒一次.'Sleep()只能在发生这种中断时完成.这里的心理图像是由"睡眠"这个词引起的,处理器实际上是睡着了而不是执行代码.只有那个时钟中断才会再次将其唤醒以恢复执行代码.
你选择的1000/60是一个非常不开心的,要求16毫秒.只是稍微过了一点,15.625所以你总是至少会在2个小时后回复:2 x 15.625 = 31 msec.你测量的是什么
然而,该中断率并不固定,可以由程序改变.它通过调用CreateTimerQueueTimer()或传统来实现timeBeginPeriod().浏览器通常需要这样做.像GIF动画一样简单需要更好的定时器,因为GIF帧时间以10毫秒为单位指定.或者通常,任何与多媒体相关的操作都需要它.
程序执行此操作的一个非常难看的副作用是这种增加的时钟中断率具有系统范围的影响.就像它在你的程序中一样.你的计时器突然变得准确,你实际上得到了你要求的睡眠持续时间,16毫秒.所以Chrome正在将速率改为每秒1000个滴答.支持的最大值.并为企业好,当你有一个竞争的操作系统.
您可以通过选择与默认中断速率更接近的睡眠持续时间来避免此问题.如果您要求15,那么您将获得15.625而Chrome不会对此产生影响.31是下一个甜蜜点.Etcetera,15.625的整数倍和向下舍入.
您遇到了分辨率问题DateTime。您应该使用Stopwatch这种精度。 Eric Lippert 表示,该DateTime值仅精确到 30 毫秒左右,因此在这种情况下,您用它获得的读数不会告诉您任何信息。
测量是你问题的一半。循环的实际时间变化是由于Sleep分辨率造成的(如其他答案中所述)。
| 归档时间: |
|
| 查看次数: |
1446 次 |
| 最近记录: |