0

ETA: Environment.TickCount を使用しても、同じ問題は発生しません。
ETA2: アプリで実際に Forms.Timer を使用していないことを追加する必要があります。これは、高頻度のタイマーの使用を無効にするためです。ここでは、コードを単純化するために使用しました。

ETA3: 以下の回答として回避策を公開しました。

I'm having problems with the StopWatch class that I'm observing on a laptop with XP but not a different laptop with Win7. Here's the test code:

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

On windows 7, checking the ellapsed milliseconds every second, I get something like: 0, 1010, 2030, 3005 ...
On XP, I get something like: 0, 200, 306, 390, 512, ...

That is, it is way off. We're not talking about milliseconds. It's nothing to do with whether the timer is high resolution, as that reports as true. As far as I know it's nothing to do with processor affinity as I've tried setting that to each of the 2 processors.

As I say, I think this is to do with XP, but it could be to do with the different cores - both laptops are, however, intel.

4

2 に答える 2

2

タイマーの間隔はどこかに設定していますか?

私には、それらが異なる間隔で実行されているように見えます。Win7 はおよそ 1 秒ごとに起動されます。XP のものは、100 ミリ秒ごとに起動できるように見えます (いくつかのサンプル ポイントが失われているため、それほど高速に読み取るのは困難です)。

デフォルトのタイマー間隔に関するドキュメントが見つかりません。文書化されていない場合は、マシン間の OS と .NET フレームワークのバージョン間で変更されている可能性があります。

于 2011-09-25T09:01:28.773 に答える
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
于 2011-09-25T11:21:25.907 に答える