在我的计算机上,秒表返回的值太低。例如,当我指定时为 200 毫秒Thread.Sleep(1000)
。该程序应该等待 1 秒。我也测试过ManualResetEvent.WaitOne(1000)
并得到相同的结果。框架 2.0 和 3.0 都给出了这种奇怪的行为。我正在运行带有 .NET Framework 3.5 SP1 的 Windows XP SP3。
这是我的测试结果(代码如下):
1000 ms for DateTime.Now.Ticks
0201 ms for Stopwatch.ElapsedTicks
0142 ms for Stopwatch.ElapsedMilliseconds
0139 ms for Stopwatch.ElapsedTicks after Reset
0264 ms for Stopwatch.ElapsedTicks setting ThreadAffinity
0151 ms for Stopwatch.ElapsedTicks setting ProcessorAffinity (and more)
0371 ms for Stopwatch.ElapsedTicks with Syncronized object
Done!
// 程序.cs 文件
class Program
{
static void Main(string[] args)
{
StopWatchTest.Go();
Console.WriteLine("Done!");
Console.ReadLine();
}
}
// StopWatchTest.cs 类
internal static class StopWatchTest
{
public const int SleepTime = 1000;
public static void Go()
{
#region Test #0 with DateTime.Now.Ticks
long startTick = DateTime.Now.Ticks;
Thread.Sleep(SleepTime);
long stopTick = DateTime.Now.Ticks;
long elapsedDt = (stopTick - startTick) * 100;
Display((int)(elapsedDt / 1000 / 1000), "DateTime.Now.Ticks");
#endregion Test #0 with DateTime.Now.Ticks
Stopwatch watch = Stopwatch.StartNew();
long frequency = Stopwatch.Frequency;
double nanosecPerTick = (1000.0 * 1000.0 * 1000.0) / frequency;
#region Test #1 with Stopwatch.ElapsedTicks
startTick = watch.ElapsedTicks;
Thread.Sleep(SleepTime);
stopTick = watch.ElapsedTicks;
double elapsedSw = (stopTick - startTick) * nanosecPerTick;
Display((int)(elapsedSw / 1000 / 1000), "Stopwatch.ElapsedTicks");
#endregion Test #1 with Stopwatch.ElapsedTicks
#region Test #2 with Stopwatch.ElapsedMilliseconds
startTick = watch.ElapsedMilliseconds;
Thread.Sleep(SleepTime);
stopTick = watch.ElapsedMilliseconds;
Display((int)(stopTick - startTick), "Stopwatch.ElapsedMilliseconds");
#endregion Test #2 with Stopwatch.ElapsedMilliseconds
#region Test #3 with Stopwatch.ElapsedTicks after Reset
watch.Stop();
watch.Reset();
watch.Start();
startTick = watch.ElapsedTicks;
Thread.Sleep(SleepTime);
stopTick = watch.ElapsedTicks;
elapsedSw = (stopTick - startTick) * nanosecPerTick;
Display((int)(elapsedSw / 1000 / 1000), "Stopwatch.ElapsedTicks after Reset");
#endregion Test #3 with Stopwatch.ElapsedTicks after Reset
#region Test #4 with Stopwatch.ElapsedTicks and ThreadAffinity
Thread.BeginThreadAffinity();
startTick = watch.ElapsedTicks;
Thread.Sleep(SleepTime);
stopTick = watch.ElapsedTicks;
elapsedSw = (stopTick - startTick) * nanosecPerTick;
Display((int)(elapsedSw / 1000 / 1000), "Stopwatch.ElapsedTicks setting ThreadAffinity");
Thread.EndThreadAffinity();
#endregion Test #4 with Stopwatch.ElapsedTicks and ThreadAffinity
#region Test #5 with Stopwatch.ElapsedTicks and ProcessorAffinity (and more)
const int affinity = 0x0001;
Process proc = Process.GetCurrentProcess();
proc.ProcessorAffinity = new IntPtr(affinity);
proc.PriorityClass = ProcessPriorityClass.High;
ProcessThreadCollection ptc = proc.Threads;
foreach (ProcessThread pt in ptc)
{
pt.IdealProcessor = 0;
pt.ProcessorAffinity = new IntPtr(affinity);
}
Thread.CurrentThread.Priority = ThreadPriority.Highest;
startTick = watch.ElapsedTicks;
Thread.Sleep(SleepTime);
stopTick = watch.ElapsedTicks;
elapsedSw = (stopTick - startTick) * nanosecPerTick;
Display((int)(elapsedSw / 1000 / 1000), "Stopwatch.ElapsedTicks setting ProcessorAffinity (and more)");
#endregion Test #5 with ProcessorAffinity and more
#region Test #6 with Syncronized object
elapsedSw = new SyncTimer().Go();
Display((int)(elapsedSw / 1000 / 1000), "Stopwatch.ElapsedTicks with Syncronized object");
#endregion Test #6 with Syncronized object
}
private static void Display(int milliseconds, string testName)
{
Console.WriteLine("{0:0000} ms for {1}", milliseconds, testName);
}
}
[Synchronization]
internal class SyncTimer : ContextBoundObject
{
[MethodImpl(MethodImplOptions.Synchronized)]
public double Go()
{
Stopwatch.StartNew();
long frequency = Stopwatch.Frequency;
double nanosecPerTick = (1000.0 * 1000.0 * 1000.0) / frequency;
long startTick = Stopwatch.GetTimestamp();
Thread.Sleep(StopWatchTest.SleepTime);
long stopTick = Stopwatch.GetTimestamp();
return (stopTick - startTick) * nanosecPerTick;
}
}
看看以下链接:
https://connect.microsoft.com/VisualStudio/feedback/details/94083/stopwatch-returns-negative-elapsed-time https://connect.microsoft.com/VisualStudio/feedback/details/94083/stopwatch-returns-negative-elapsed-time
System.Diagnostics.Stopwatch 在 Elapsed... 属性中返回负数 https://stackoverflow.com/questions/1008345/system-diagnostics-stopwatch-returns-negative-numbers-in-elapsed-properties
秒表的准确性似乎存在问题,可能导致它返回负的经过时间,并且时间变化很大。如果您查看 Connect 问题,大多数人都在谈论在虚拟机上看到该问题,这就是我们看到负 Elapsed 值问题的地方。
看着查询性能计数器文档 http://msdn.microsoft.com/en-us/library/ms644904%28VS.85%29.aspx,这似乎意味着由于 BIOS 或硬件抽象层错误,此问题可能会发生在多处理器系统上,但没有提供进一步的信息,也没有具体说明虚拟机。
至于这个问题的解决方案......我在很多谷歌搜索中都没有找到解决方案。您可以忽略小于零的值,这并不理想,但在某些情况下是可行的。但这并不能解决您的问题 - 您如何知道哪些值无效?
希望这会有所帮助。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)