现在的位置: 首页 > 综合 > 正文

NETCF开发之比较两种Timer类

2012年06月18日 ⁄ 综合 ⁄ 共 4329字 ⁄ 字号 评论关闭

如果要求线程按照规定的时间间隔周期性地执行的话,可以使用Timer类将需要调用的方法加入队列等待周期性执行。Timer类包含在System.Threading命名空间。Timer类通过系统提供的线程池线程在每次计时器期满时运行计时器委托。因为System.Threading.Timer对象是在单独的线程中执行,因此在退出应用程序之前需要完全终止计时器。

.NET Compact Framework中的其他Timer类,比如System.Windows.Forms命名空间的Timer类与System.Threading命名空间的Timer类有所不同。System.Windows.Forms.Timer类每次计时器期满时产生WM_TIMER系统消息来触发事件,不能使用单独的线程来执行。System.Windows.Forms.Timer类使用简单且适合用于周期性的更新用户界面。如果需要高精度的计时器,则应该使用System.Threading.Timer

23-3展示了使用不同Timer类的精确程度比较。在如图23-3所示的应用程序中分别创建了System.Threading.TimerSystem.Windows.Forms.Timer实例,并设置时间间隔为100毫秒。

 


23-3:不同Timer类的精确性比较

 

这个TimerDemo应用程序测量不同Timer类的平均时间间隔。当点击“模拟界面操作”按钮时,应用程序产生一个额外的处理活动,使不同Timer类在行为上的差别更加清晰明显。Windows.Forms.Timer对象从消息队列接收到一个WM_TIMER消息时调用它自己的委托。Windows.Forms.Timer是单线程组件,精度限定为55毫秒。当应用程序处理繁忙时,时间间隔小于55毫秒的WM_TIMER消息会被忽略。换句话说,由于Windows.Forms.Timer的精度限制,消息队列中不能存在超过一个未处理的WM_TIMER消息,否则多余的WM_TIMER消息会重叠合并,因而丢失计时信号。而在图23-3中正确的做法是,Threading.Timer对象运行在一个单独的线程中,计时器的间隔时间一到则随时被运行。Threading.Timer对象负责处理精确度(两个Timer类的处理次数),因为“模拟界面操作”按钮被点击后,主线程的优先级被临时降低,以此模拟应用程序处于繁忙状态。清单23-7说明了TimerDemo应用程序的实现代码。

 

清单23-7TimerDemo应用程序实现代码


Public Class TimerDemo

 

    Private threadingTimer As Threading.Timer

    Private prevTimerTicks As Long

    Private avgTimerTicks As Long

    Private numTimerExpirations As Long

    Private timerRunning As Boolean = False

 

    Private Sub btnThreadingTimer_Click(ByVal sender As System.Object, _

ByVal e As System.EventArgs) Handles btnThreadingTimer.Click

If timerRunning = True Then

timerRunning = False

While Not threadingTimer Is Nothing

Threading.Thread.Sleep(0)

End While

avgTimerTicks = avgTimerTicks / numTimerExpirations

                lThreadingTimer.Text = "Avg. Timer Interval: " + avgTimerTicks.ToString() + _

" ms (" + numTimerExpirations.ToString() + ")"

                btnThreadingTimer.Text = "Start Threading Timer"

                btnFormsTimer.Enabled = True

           Else

                timerRunning = True

                lThreadingTimer.Text = "Timer running"

                btnThreadingTimer.Text = "Stop Threading Timer"

                btnFormsTimer.Enabled = False

                avgTimerTicks = 0

                numTimerExpirations = 0

                prevTimerTicks = Environment.TickCount

                threadingTimer = New Threading.Timer(New _

Threading.TimerCallback(AddressOf ThreadingTimerTick), Nothing, 0, 100)

           End If

    End Sub

 


Private Sub btnFormsTimer_Click(ByVal sender As System.Object, _

ByVal e As System.EventArgs) Handles btnFormsTimer.Click

If timerRunning = True Then

timerRunning = False

 

                avgTimerTicks = avgTimerTicks / numTimerExpirations

                lFormsTimer.Text = "Avg. Timer Interval: " + avgTimerTicks.ToString() + _

" ms (" + numTimerExpirations.ToString() + ")"

                btnFormsTimer.Text = "Start Forms Timer"

                btnThreadingTimer.Enabled = True

           Else

                timerRunning = True

                lFormsTimer.Text = "Timer running"

                btnFormsTimer.Text = "Stop Forms Timer"

                btnThreadingTimer.Enabled = False

                avgTimerTicks = 0

                numTimerExpirations = 0

                prevTimerTicks = Environment.TickCount

                formsTimer.Interval = 100   ' 利用窗体上放置的Timer控件

                formsTimer.Enabled = True

           End If

End Sub

 

Private Sub btnProcessing_Click(ByVal sender As System.Object, _

ByVal e As System.EventArgs) Handles btnProcessing.Click

           btnProcessing.Enabled = False

           Threading.Thread.CurrentThread.Priority = Threading.ThreadPriority.BelowNormal

           For i As Long = 0 To 5000000

           Next

           btnProcessing.Enabled = True

           Threading.Thread.CurrentThread.Priority = Threading.ThreadPriority.Normal

    End Sub

 

    Private Sub ThreadingTimerTick(ByVal state As Object)

           If timerRunning = False Then

                threadingTimer.Dispose()

                threadingTimer = Nothing

           Else

                Dim currentTimerTicks As Long = Environment.TickCount

                avgTimerTicks = avgTimerTicks + (currentTimerTicks - prevTimerTicks)

                numTimerExpirations = numTimerExpirations + 1

                prevTimerTicks = currentTimerTicks

           End If

    End Sub

 


Private Sub formsTimer_Tick(ByVal sender As System.Object, _

ByVal e As System.EventArgs) Handles formsTimer.Tick

If timerRunning = False Then

formsTimer.Enabled = False

                formsTimer = Nothing

           Else

                Dim currentTimerTicks As Long = Environment.TickCount

                avgTimerTicks = avgTimerTicks + (currentTimerTicks - prevTimerTicks)

                numTimerExpirations = numTimerExpirations + 1

                prevTimerTicks = currentTimerTicks

           End If

    End Sub

 

End Class

 

抱歉!评论已关闭.