秒表可以返回负值是否正常?下面的代码示例可用于重现它.
while (true)
{
Stopwatch sw = new Stopwatch();
sw.Start();
sw.Stop();
if (sw.ElapsedMilliseconds < 0)
Debugger.Break();
}
Run Code Online (Sandbox Code Playgroud)
我可以重现负数的唯一地方是我的虚拟机(由8核机器上的Hyper-V托管)
Mic*_*ren 17
这是一个错误.它似乎并没有引起很多关注,所以我建议跟进那份报告.
在平凡的解决办法似乎是忽略负值:
long elapsedMilliseconds = Math.Max(0, stopwatch.ElapsedMilliseconds);
Run Code Online (Sandbox Code Playgroud)
Jam*_*ton 12
我使用Reflector在.NET 2.0和.NET 4.0中反编译了Stopwatch类,然后比较差异以了解它是如何修复的.除了添加新的Restart方法之外,这是我发现的差异:
public void Stop()
{
if (this.isRunning)
{
long num2 = GetTimestamp() - this.startTimeStamp;
this.elapsed += num2;
this.isRunning = false;
// THE NEXT 4 LINES ARE NEW IN .NET 4.0:
if (this.elapsed < 0L)
{
this.elapsed = 0L;
}
}
}
Run Code Online (Sandbox Code Playgroud)
所以基本上,如果值为负,它们会在Stop方法中设置为0.还有bug恕我直言:
编辑: 不幸的是,#2和#3超出了.NET Framework的强大功能:
以下是问题的核心:来自QueryPerformanceCounter上的MSDN,它是Stopwatch类使用的API:
在多处理器计算机上,调用哪个处理器无关紧要.但是,由于基本输入/输出系统(BIOS)或硬件抽象层(HAL)中的错误,您可以在不同的处理器上获得不同的结果.要指定线程的处理器关联,请使用SetThreadAffinityMask函数.
不要只使用.NET 4.0秒表并假设问题得到解决.它不是,除非你希望它们与你的线程亲和力混淆,否则它们无法做任何事情.从Stopwatch类文档:
在多处理器计算机上,线程运行在哪个处理器上并不重要.但是,由于BIOS或硬件抽象层(HAL)中的错误,您可以在不同的处理器上获得不同的时序结果.要指定线程的处理器关联,请使用ProcessThread.ProcessorAffinity方法.
| 归档时间: |
|
| 查看次数: |
4523 次 |
| 最近记录: |