蜱虫不一致且波动

时间:2016-06-25 04:08:06

标签: vb.net visual-studio debugging time stopwatch

我有一个子按钮。代码是这样的:

Private Sub plus(ByRef a As Integer)
    For i = 0 To a
        a = a + a
    Next
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Dim i As Integer = 19
    Dim sw As New Stopwatch
    sw.Start()
    plus(i)
    sw.Stop()
    MsgBox(sw.ElapsedTicks)
End Sub

当我运行sub时,单击“button1”程序输出310即表示310是sw.elapsedticks

当我再次点击“button1”再次运行sub时,程序输出1<< JUST ONE ellapsedticks

怎么会这样?

我试图停止我的vb.net程序,然后再次运行它,然后我再次点击它的按钮,它发生了同样的情况,这是值得272秒表经过时间点然后我再次点击秒表后,再次点击再次为1 < / p>

请解释为什么会发生这种情况?

1 个答案:

答案 0 :(得分:0)

StopWatch类将回退到使用DateTime类,如果您的硬件不支持高性能计数器,则使用滴答作为测量。现在,大多数计算机都在使用高性能计数器,至少从Windows 2000及更高版本开始。考虑到这一点,.NET Stopwatch类基于此高频计时器。通常,调用Start会查询性能计数器并存储该值。当您Stop时,它会再次查询性能计数器。然后经过的时间是这两个值的简单减法,以便为您提供ElapsedTicks

  

以下是一些需要进一步解释的项目......

此属性只调用GetRawElapsedTicks()

  public long ElapsedTicks { 
        get { return GetRawElapsedTicks(); }
  }

以下函数返回从秒表启动到调用秒表Stop方法所经过的实际时间。如上所述,the elapsed time is a simple subtraction of those two values您可以在下方看到:currentTimeStamp - startTimeStamp

 // Get the elapsed ticks.        
#if FEATURE_NETCORE
        public long GetRawElapsedTicks() {
#else
        private long GetRawElapsedTicks() {
#endif
            long timeElapsed = elapsed;

            if( isRunning) {
                // If the StopWatch is running, add elapsed time since
                // the Stopwatch is started last time. 
                long currentTimeStamp = GetTimestamp();                 
                long elapsedUntilNow = currentTimeStamp - startTimeStamp;
                timeElapsed += elapsedUntilNow;
            }
            return timeElapsed;
        }  

上面你可能会注意到#if FEATURE_NETCORE,并想知道它是什么。这些被称为预处理器命令。基本上它们像if-else语句一样工作,除非如果条件不满足,它将不会在编译时包含代码,因为它是预编译决策而不是运行时...

总而言之,Hans Passant已经提到了关于及时(JIT)编译的内容。我上面提到的所有这些都进一步打破了这个解释。 差异 的真正原因是它需要花时间编译并首次运行

另外要提的是。 stopwatch类使用long变量类型来存储他们称之为frequency的内容。频率“存储高分辨率性能计数器的频率(如果存在),否则它将存储TicksPerSecond。 频率在系统运行时不能改变,因此它只被初始化一次。

以下是其他constants,它们与频率有很大关系以及如何计算频率。

 private const long TicksPerMillisecond = 10000;
 private const long TicksPerSecond = TicksPerMillisecond * 1000;

当您创建StopWatch类的新实例时,这就是运行的内容。

bool succeeded = SafeNativeMethods.QueryPerformanceFrequency(out Frequency);            
            if(!succeeded) {
                IsHighResolution = false; 
                Frequency = TicksPerSecond;
                tickFrequency = 1;
            }
            else {
                IsHighResolution = true;
                tickFrequency = TicksPerSecond;
                tickFrequency /= Frequency;
            }

您现在可以看到的频率,在设置 如何计算已用时间 以及tick的频率方面发挥重要作用将要发生。即使您停止了应用程序,也无关紧要,因为此时存储频率。 重置频率 的唯一方法是重新启动计算机。