我有一个子按钮。代码是这样的:
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>
请解释为什么会发生这种情况?
答案 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
的频率方面发挥重要作用将要发生。即使您停止了应用程序,也无关紧要,因为此时存储频率。 重置频率 的唯一方法是重新启动计算机。