我搜索了这个问题,但没有看到答案.如果它是重复的,我很乐意关闭它.
我目前正在尝试对某项技术进行一些性能评估,并看到一些相当令人难以置信的结果,所以我决定尝试一些.在那我想试着看看秒表类是否回归了我的预期.
Stopwatch sw = Stopwatch.StartNew();
Thread.Sleep(1);
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我几乎看到了15毫秒的返回值.我理解DateTime的分辨率在那附近但是不应该Thread.Sleep(1)睡一个线程1ms?我所使用的系统返回Stopwatch.IsHighResolution true并在.NET 4中运行.
背景:此代码以完整和正确的形式用于收集有关Aerospike db get请求的一些数字.数据库不在同一个盒子里.当我在查询处于中间时打印出sw.ElapsedMilliseconds时,我看到的主要是亚毫秒响应,这听起来有点怀疑,因为我的Java等效代码在大多数情况下返回更加可信的5ms-15ms响应.Java代码使用的是System.nanoTime()的区别.通过我的C#代码中的submilli响应,我的意思是Console.WriteLine(sw.ElapsedMilliseconds)打印0.
Han*_*ant 29
定时器等比秒表由时钟中断递增.默认情况下,Windows上每秒运行64次.或15.625毫秒.所以一个小于16的Thread.Sleep()参数不会给你你所寻找的延迟,你总是会得到至少15.625的间隔.类似地,如果您读取,例如,Environment.TickCount或DateTime.Now并等待少于 16毫秒,那么您将读回相同的值并认为已经过了0毫秒.
始终使用秒表进行小增量测量,它使用不同的频率源.它的分辨率是可变的,它取决于主板上的芯片组.但你可以依靠它优于微秒.Stopwatch.Frequency为您提供费率.
时钟中断率可以改变,你必须pinvoke timeBeginPeriod().这可以让你降到一毫秒,实际上使Thread.Sleep(1)准确.最好不要这样做,这是非常不友好的力量.
我希望它Thread.Sleep只不过是围绕Win32 SleepAPI 的托管包装器.众所周知,该API函数具有低分辨率.文档说明了这一点:
此函数使线程放弃其时间片的剩余部分,并在基于dwMilliseconds值的时间间隔内变得不可用.系统时钟以恒定速率"滴答".如果dwMilliseconds小于系统时钟的分辨率,则线程可能会睡眠时间少于指定的时间长度.如果dwMilliseconds大于一个tick但小于2,则等待可以是一到两个滴答之间的任何位置,依此类推.要提高休眠间隔的准确性,请调用timeGetDevCaps函数以确定支持的最小计时器分辨率,并调用timeBeginPeriod函数以将计时器分辨率设置为最小值.调用timeBeginPeriod时请小心,因为频繁的调用会显着影响系统时钟,系统电源使用和调度程序.如果你调用timeBeginPeriod,
休眠间隔过后,线程就可以运行了.如果指定0毫秒,则线程将放弃其时间片的剩余部分但仍保持准备状态.请注意,不保证立即运行就绪线程.因此,线程可能在睡眠间隔过去一段时间后才运行.有关更多信息,请参阅计划优先级.
所以,您可以使用timeBeginPeriod和timeEndPeriod建议增加计时器分辨率,但实际上不建议这样做.如果你真的需要短时间阻止,那么我建议你找到一个更好的解决方案.例如多媒体计时器.
| 归档时间: |
|
| 查看次数: |
2845 次 |
| 最近记录: |