ETA:使用Environment.TickCount不会出现同样的问题 ETA2:我应该补充一点,我实际上并没有在我的应用程序中使用Forms.Timer - 就像这样 否定使用高频定时器。我在这里用它来简化代码。
ETA3:我在下面发表了一个解决方法作为答案。
我遇到了StopWatch类的问题,我在使用XP的笔记本电脑上观察到但没有使用Win7的笔记本电脑。这是测试代码:
Public Class FormTest
Inherits Form
Private WithEvents Timer1 As System.Windows.Forms.Timer = New System.Windows.Forms.Timer
Private sw As Stopwatch = New Stopwatch
Public Sub New()
Me.Timer1.Interval = 1
End Sub
Protected Overrides Sub OnClick(ByVal e As System.EventArgs)
MyBase.OnClick(e)
Me.sw.Start()
Me.Timer1.Start()
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Me.Text = sw.ElapsedMilliseconds.ToString
Me.Update()
End Sub
End Class
在Windows 7上,每秒检查一次经过的毫秒,我得到的结果如下: 0,1010,2030,3005 ...... 在XP上,我得到类似的东西:0,200,306,390,512,......
也就是说,它已经过时了。我们不是在谈论毫秒。 它与定时器是否为高分辨率无关,因为它报告为真。如 据我所知,它与处理器关联性无关,因为我已经尝试将其设置为2个处理器中的每一个。
正如我所说,我认为这与XP有关,但它可能与不同的内核有关 - 但是,笔记本电脑都是英特尔。
答案 0 :(得分:2)
您是否在任何地方设置了计时器的间隔?
对我来说,它们似乎以不同的间隔运行。 Win7大致每秒都会被解雇。 XP看起来可能每100毫秒就会被触发一次(错过了几个样本点 - 很难快速读取内容)。
我找不到有关默认计时器间隔的任何文档。如果它没有文档,它可能在您的机器之间的OS和.NET框架版本之间进行了更改。
答案 1 :(得分:0)
我已经使用 timeGetTime 方法解决了这个问题。以下代码是 基本上是 Diagnostics.StopWatch 类,但 QueryPerformanceCounter 调用已替换为 timeGetTime 。
我还没有完全测试过它*但是,从我读过的内容来看,我应该可以打电话给 TimeBeginPeriod(1)以实现符合框架秒表的分辨率。
(*如果现在已经完全测试过,它确实达到了毫秒精度)。
如果有人能告诉我如何使QueryPerformanceCounter适用于XP(如果确实是XP的问题),或者检测是否存在问题,我会取消标记并将其标记为答案。
Imports System.Runtime.InteropServices
Friend Class StopWatch
Private Elapsed As Integer
Private StartTimeStamp As Integer
Public Sub Start()
If Not Me._IsRunning Then
Me.StartTimeStamp = StopWatch.timeGetTime
Me._IsRunning = True
End If
End Sub
Public Sub [Stop]()
If Me.isRunning Then
Me.Elapsed = (Me.Elapsed + (StopWatch.timeGetTime - Me.StartTimeStamp))
Me._IsRunning = False
If (Me.Elapsed < 0) Then
Me.Elapsed = 0
End If
End If
End Sub
Public Sub Reset()
Me.Elapsed = 0
Me._IsRunning = False
Me.StartTimeStamp = 0
End Sub
Private _IsRunning As Boolean
Public ReadOnly Property IsRunning() As Boolean
Get
Return Me._IsRunning
End Get
End Property
Public ReadOnly Property ElapsedMilliseconds() As Integer
Get
Dim elapsed = Me.Elapsed
If Me._IsRunning Then
elapsed = (elapsed + (StopWatch.timeGetTime - Me.StartTimeStamp))
End If
Return elapsed
End Get
End Property
<DllImport("winmm.dll", SetLastError:=True)> _
Private Shared Function timeGetTime() As Integer
End Function
End Class