Diagnostics.StopWatch время задержки в XP, но не в Win7 - PullRequest
0 голосов
/ 25 сентября 2011

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, ...

То есть это далеко.Мы не говорим о миллисекундах.Это не имеет никакого отношения к тому, является ли таймер высоким разрешением, поскольку это сообщает как истинное.Насколько я знаю, это никак не связано со сродством процессоров, так как я пытался установить его для каждого из двух процессоров.

Как я уже сказал, я думаю, что это связано с XP, но это может бытьделать с разными ядрами - оба ноутбука, однако, Intel.

Ответы [ 2 ]

2 голосов
/ 25 сентября 2011

Вы устанавливаете интервал таймера где-нибудь?

Мне кажется, они работают с разными интервалами. Win7 запускается примерно каждую секунду. Похоже, что XP запускается каждые 100 мс (при пропущенных нескольких точках выборки - трудно читать вещи так быстро).

Я не могу найти никакой документации по таймеру по умолчанию. Если он не задокументирован, он может быть изменен между версиями ОС и .NET на ваших машинах.

0 голосов
/ 25 сентября 2011

Я решил проблему с помощью метода 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
...