【问题标题】:Diagnostics.StopWatch time lag in XP but not Win7XP 中的 Diagnostics.StopWatch 时间滞后,但 Win7 中没有
【发布时间】:2011-09-25 08:49:41
【问题描述】:

ETA:使用 Environment.TickCount 不会出现同样的问题。
ETA2:我应该补充一点,我实际上并没有在我的应用程序中使用 Forms.Timer - 因为这会 否定使用高频定时器。我在这里使用它来简化代码。

ETA3:我在下面发布了一个解决方法作为答案。

我在一台装有 XP 的笔记本电脑上观察到 StopWatch 类时遇到问题,但在另一台装有 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 有关,但也可能与不同的内核有关 - 然而,两台笔记本电脑都是英特尔的。

【问题讨论】:

  • 您是在使用两台笔记本电脑还是在一台笔记本电脑上双启动?
  • 我看不到你在哪里设置了Timer1 计时器的时间间隔?
  • 见鬼,粘贴后永远不要清理代码!我已经重新添加了部分。间隔是 1,对于 Forms.Timer,我认为相当于每秒大约 30 次。
  • @Mike 这是两台不同的笔记本电脑
  • 定时器间隔精度受硬件和windows线程调度的限制。具有不同操作系统的两台机器之间可能会有很大的不同。

标签: c# .net vb.net timing stopwatch


【解决方案1】:

你是否在任何地方设置了定时器的时间间隔?

在我看来,它们的运行时间间隔不同。 Win7 大约每秒触发一次。 XP 看起来可以每 100 毫秒触发一次(缺少一些样本点 - 很难快速读取内容)。

我找不到有关默认计时器间隔的任何文档。如果它没有记录,它可能已经在您的机器之间的 OS 和 .NET 框架版本之间进行了更改。

【讨论】:

  • 您好,Win7 计时器不是每秒触发一次,我只是每秒记录一下表单文本。
  • 定时器有一些默认值,它可能在操作系统之间有所不同。如果在 Win7 上是一秒钟,您将只能每秒获得更新。此外,“每秒做一个笔记”似乎是一种非常不科学的方法。
  • 我在上面的cmets中看到我错误地删除了一部分代码; Me.Timer1.Interval = 1.
  • @Anders - 我现在明白为什么你认为它每秒都在触发,因为我错误地删除了部分代码。 Me.Timer1.Interval = 1.
【解决方案2】:

我已经通过使用 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-29
    • 2014-06-17
    • 2010-12-09
    • 1970-01-01
    • 2022-11-21
    • 1970-01-01
    • 1970-01-01
    • 2017-12-08
    相关资源
    最近更新 更多