使用 System.Timers.Timer 更新TrackBar1 UI时发生跨线程的错误
我的问题如标题 小弟在设计用System.Timers.Timer 这个定时器去累加 TrackBar1的位置 结果却跑出跨线程的错误
我上网查了些资讯 好似说要用委派及将更新的form类别丢进去这些信息
我参考了网络上的信息 写了些代码 但还是出现跨线程错误
应该是我的委派的代码好像写得有点问题 请各位大大指导一下
这边该怎么写才对
Private newtime As New System.Timers.Timer
Private Sub Button3_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
'If Timer4.Enabled = False Then
' Me.Timer4.Start()
'End If
'==============System.Timers.Timer
AddHandler newtime.Elapsed, AddressOf Timers_Timer_Elapsed
newtime.Interval = 20
newtime.Start()
'==============
End Sub
Sub Timers_Timer_Elapsed()
Me.newtime.SynchronizingObject = Me
Me.BeginInvoke(New UpdateControl(AddressOf _mUpdateControl), New Object() {TrackBar1})
If Not TrackBar1.Value = TrackBar1.Maximum Then
'Me.TrackBar1.Value += 1
Me.BeginInvoke(New UpdateControl(AddressOf _mUpdateControl), New Object() {TrackBar1})
Else
TrackBar1.Value = 0
newtime.Stop()
End If
End Sub
Private Delegate Sub UpdateControl(ByVal Ctrl As TrackBar)
Private _objLock As New Object()
Private Sub _mUpdateControl(ByVal Ctrl As TrackBar)
SyncLock Me._objLock
If TypeOf Ctrl Is TrackBar Then
Ctrl.Value += 1
End If
End SyncLock
End Sub
--------------------编程问答-------------------- TrackBar1.Value = TrackBar1.Maximum
所有操作界面的语句,无论读写,都要放在委托中。
另外,用Invoke而不是BeginInvoke,因为你这里需要同步处理。 --------------------编程问答--------------------
Private newtime As New System.Timers.Timer--------------------编程问答-------------------- 当然,你的这段程序可以这样写
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
AddHandler newtime.Elapsed, AddressOf Timers_Timer_Elapsed
newtime.Interval = 20
newtime.Start()
End Sub
Sub Timers_Timer_Elapsed()
Me.BeginInvoke(Sub()
If Not TrackBar1.Value = TrackBar1.Maximum Then
TrackBar1.Value += 1
Else
TrackBar1.Value = 0
newtime.Stop()
End If
End Sub)
End Sub
Private newtime As New System.Timers.Timer
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Me.newtime.SynchronizingObject = Me
AddHandler newtime.Elapsed, AddressOf Timers_Timer_Elapsed
newtime.Interval = 20
newtime.Start()
End Sub
Sub Timers_Timer_Elapsed()
If Not TrackBar1.Value = TrackBar1.Maximum Then
TrackBar1.Value += 1
Else
TrackBar1.Value = 0
newtime.Stop()
End If
End Sub
这是因为你的 Elapsed 中的处理,其实都没有什么“后台处理意味”,都是简单地更新界面上的控件,所以他们需要全都放在主线程执行。因此这里怎么写都可以。
你的这个例子并不能显示线程编程的好处,只是说明了线程中操作控件必须额外多写一行委托而已。 --------------------编程问答-------------------- 我这边的需求是这样 我要设计一个以1ms为单位的累加定时器 去比对要触发另一个动作的时间去触发动作 但我不希望当触发动作时累加定时器就因为要去跑触发动作的程序 然后就不继续累加计时了 所以这里才选择设计成一个独立线程的timer
再来听到板主大大的回文再加上sp1234 大大的回文 我整理一下思绪 我这里需要的功能 似乎是需要能同时动作的 也就是说累加定时器照常在跑并移动TrackBar1 然后另一个timer则是不断每隔1ms就去比对要触发动作的时间点
所以我应该是要用Invoke 做同步处理
Me.Invoke(Sub()
If Not TrackBar1.Value = TrackBar1.Maximum Then
TrackBar1.Value += 1
Else
TrackBar1.Value = 0
newtime.Stop()
End If
End Sub)
补充:.NET技术 , VB.NET