我认为System.Timers.Timer创建了自己的线程,并且Microsoft建议这种类型的计时器执行更准确计时的任务(而不是在UI线程中运行的Windows.Forms.Timer) )。
下面的代码(我认为)应该可以复制并粘贴到一个空表单的项目中。在我的机器上,我无法让tmrWork以每秒大约60次的速度打勾,并且它非常不稳定。
Public Class Form1
Private lblRate As New Windows.Forms.Label
Private WithEvents tmrUI As New Windows.Forms.Timer
Private WithEvents tmrWork As New System.Timers.Timer
Public Sub New()
Me.Controls.Add(lblRate)
InitializeComponent()
End Sub
Private StartTime As DateTime = DateTime.Now
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) _
Handles MyBase.Load
tmrUI.Interval = 100
tmrUI.Enabled = True
tmrWork.Interval = 1
tmrWork.Enabled = True
End Sub
Private Counter As Integer = 0
Private Sub tmrUI_Tick(sender As Object, e As System.EventArgs) _
Handles tmrUI.Tick
Dim Secs As Integer = (DateTime.Now - StartTime).TotalSeconds
If Secs > 0 Then lblRate.Text = (Counter / Secs).ToString("#,##0.0")
End Sub
Private Sub tmrWork_Elapsed(sender As Object, e As System.Timers.ElapsedEventArgs) _
Handles tmrWork.Elapsed
Counter += 1
End Sub
End Class
在这个特殊的简单情况下,将所有内容放在tmrUI中将产生相同的性能。我想我从来没有试过让System.Timers.Timer过快,但这个性能对我来说太糟糕了。我编写了自己的类来在硬件中使用高性能计时器,但似乎应该有一个可以做的内置计时器,比如说每秒100个滴答?
这里发生了什么?
答案 0 :(得分:-1)
要接近100Hz,请尝试使用AutoResetEvent。
Private Sub tmrWork()
'start this as a background thread
Dim tmr As New Threading.AutoResetEvent(False)
Dim stpw As Stopwatch = Stopwatch.StartNew
Const interval As Integer = 10 'the interval
'
'
Do 'timer
stpw.Stop()
If stpw.ElapsedMilliseconds > interval Then
tmr.WaitOne(interval) 'the interval
Else
tmr.WaitOne(CInt(interval - stpw.ElapsedMilliseconds)) 'the interval
End If
stpw.Restart()
'
'code to execute when 'timer' elapses
'
Loop
End Sub
这是一个测试,表明根据您在循环中的操作,可以以100Hz的频率触发代码。
Private Sub tmrWork()
Dim tmr As New Threading.AutoResetEvent(False)
Dim stpw As Stopwatch = Stopwatch.StartNew
Const interval As Integer = 10 'the interval
'for testing
Dim cts As New List(Of Long)
'
'
Do 'timer
tmr.WaitOne(interval) 'wait for the interval
cts.Add(stpw.ElapsedMilliseconds) 'add elapsed to list
stpw.Restart() 'restart
If cts.Count >= 500 Then 'five second test
Debug.WriteLine(String.Format("Avg: {0}, Min: {1}, Max: {2}", cts.Average, cts.Min, cts.Max))
Stop
End If
Loop
End Sub
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Dim t As New Threading.Thread(AddressOf tmrWork)
t.IsBackground = True
t.Start()
End Sub
Hans Pissant
平台计时器分辨率:平台计时器分辨率默认平台计时器分辨率为15.6毫秒(15625000ns),应在系统空闲时使用。如果定时器分辨率增加,则处理器电源管理技术可能无效。由于多媒体回放或图形动画,可以增加定时器分辨率。电流定时器分辨率(100ns单位)100000最大定时器周期(100ns单位)156001
平台计时器分辨率:未完成的计时器请求程序或服务请求的计时器分辨率小于平台最大计时器分辨率。请求的期间100000请求进程ID 452请求进程路径\ Device \ HarddiskVolume3 \ Windows \ System32 \ svchost.exe