我叫timeBeginPeriod(1),但是没有用

时间:2019-04-10 10:59:56

标签: c# windows multithreading

Window的Thread.Sleep()默认精度为15.625 ms(1000/64),即如果调用Thread.Sleep(1),则经过的时间为15 ms或16 ms。我想将精度提高到1毫秒。

有一个函数“ timeBeginPeriod”可以更改精度。但是我没有得到我想要的。这是我的代码:

[DllImport("winmm.dll", EntryPoint = "timeBeginPeriod")]
public static extern void TimeBeginPeriod(int t);

[DllImport("winmm.dll", EntryPoint = "timeEndPeriod")]
public static extern void TimeEndPeriod(int t);

TimeBeginPeriod(1);
var t1 = Environment.TickCount;
Thread.Sleep(1);
var t2 = Environment.TickCount;
Console.WriteLn(t2 - t1);
TimeEndPeriod(1);

我期望的是1或2,但实际上是15或16。

我错过了任何代码吗?

2 个答案:

答案 0 :(得分:0)

基于各种论坛上的讨论,我怀疑Windows 10上的此功能有一段时间被打破,但是它似乎已在运行Windows 10 2004版的计算机上修复。无需调用timeBeginPeriod,即睡眠计时器分辨率约为15ms。调用timeBeginPeriod(1)之后,睡眠计时器分辨率降低到1..2 ms

其他人可以在最新的Windows系统上确认吗?

附录1:我刚刚发现https://stackoverflow.com/a/48011619/295690,它指示即使该功能可能实际上已被修复,还是有充分的理由避免使用它。

附录2:来自https://randomascii.wordpress.com/2013/07/08/windows-timer-resolution-megawatts-wasted/的更多见解使我认为,这不仅仅是操作系统版本的问题。我完全可以想象,某些省电模式或硬件配置会阻止程序增加系统范围的滴答频率。

答案 1 :(得分:0)

我对此问题有一些更新。

Environment.TickCount的精度大约为16ms。这不是一种高精度方法。实际上,通过使用DateTime,即使在Windows 10版本1903上不使用TimeBeginPeriod / TimeEndPeriod,我们也可以获得更准确的经过时间。

long t1 = Environment.TickCount;
DateTime dt1 = DateTime.Now;
Thread.Sleep(1);
DateTime dt2 = DateTime.Now;
long t2 = Environment.TickCount;
Console.WriteLine("DateTime Method: " + (dt2-dt1).TotalMilliseconds);
Console.WriteLine("TickCount Method: " + (t2 - t1));

DateTime Method: 2.0074
TickCount Method: 0