2 knight chester sun Knight_Chester_Sun 于 2015.06.13 15:35 提问

如何在线程上使用timer来做一个定时器 in VB.NET

代码如下。思路是这样的:在线程中使用threading.timer,1ms执行一次,使GLO_TICK++。Calculate_Interval 用来计算间隔时间。
实际上TimerTask不是1ms执行一次,这是为什么?

 Module Module1
    Class StateObjClass
        ' Used to hold parameters for calls to TimerTask 
        Public SomeValue As Integer
        Public TimerReference As System.Threading.Timer
        Public TimerCanceled As Boolean
        Public GLO_TICK As Long
    End Class

    Public StateObj As New StateObjClass
    Public long_Temp1 As Long
    Public int16_temp1 As Int16

    Sub RunTimer()

        StateObj.TimerCanceled = False
        StateObj.SomeValue = 1
        Dim TimerDelegate As New Threading.TimerCallback(AddressOf TimerTask)
        ' Create a timer that calls a procedure every 2 seconds. 
        ' Note: There is no Start method; the timer starts running as soon as  
        ' the instance is created. 
        Dim TimerItem As New System.Threading.Timer(TimerDelegate, StateObj, _
                                                   0, 1)
        StateObj.TimerReference = TimerItem  ' Save a reference for Dispose.
        Dim a As Boolean = False

        Dim state As Int16
        While True ' Run for ten loops.
            'System.Threading.Thread.Sleep(1000)  ' Wait one second.

            Select Case state
                Case 0
                    If a Then
                        long_Temp1 = StateObj.GLO_TICK
                    Else
                        a = True
                        long_Temp1 = StateObj.GLO_TICK
                        Console.WriteLine("a=" & a & Now)
                    End If
                    state = 1
                    Exit Select
                Case 1
                    Calculate_Interval(long_Temp1, int16_temp1)
                    If int16_temp1 > 100 Then
                        a = False
                        long_Temp1 = StateObj.GLO_TICK
                        Console.WriteLine("a=" & a & Now)
                        state = 2
                    End If
                    Exit Select
                Case 2
                    Calculate_Interval(long_Temp1, int16_temp1)
                    If int16_temp1 > 100 Then
                        a = True
                        long_Temp1 = StateObj.GLO_TICK
                        Console.WriteLine("a=" & a & Now)
                        state = 1
                    End If
                    Exit Select
            End Select

        End While

        StateObj.TimerCanceled = True  ' Request Dispose of the timer object.
    End Sub

    Sub TimerTask(ByVal StateObj As Object)
        Dim State As StateObjClass = CType(StateObj, StateObjClass)

        If State.TimerCanceled Then    ' Dispose Requested.
            System.Diagnostics.Debug.WriteLine("Done  " & Now)
            State.TimerReference.Dispose()
        End If

        System.Threading.Interlocked.Increment(State.GLO_TICK)
    End Sub
    Sub Main()
        RunTimer()
        Console.Read()

    End Sub

    Function Calculate_Interval(ByVal IntervalStart As Long, ByRef Interval_ms As Int16) As Int16
        Interval_ms = Convert.ToInt16(StateObj.GLO_TICK - IntervalStart)
        Return Interval_ms
    End Function

End Module

1个回答

caozhy
caozhy   Ds   Rxr 2015.06.13 16:41

没有定时器能保证1ms的定时精度。你非要这么做,得死循环。

Knight_Chester_Sun
Knight_Chester_Sun 回复caozhy: 有什么好的方法能够做realtime吗? 我暂时使用解决了上面的问题Environment.tick
2 年多之前 回复
caozhy
caozhy 回复Knight_Chester_Sun: 10毫秒~100毫秒级,并且windows不是rtos,还受到进程优先级和其它程序的限制。
2 年多之前 回复
Knight_Chester_Sun
Knight_Chester_Sun 那最多能精确到什么单位?
2 年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片