VB线程计时器更新UI
VB Thread Timer Update UI
我制作了一个小程序,允许针对每个单击的按钮进行单独的计时器倒计时。 (例如,点击按钮 1 将开始按钮 1 的倒计时,同时更新按钮本身的文本以反映剩余时间。)
我现在担心的是,我不确定我的程序在长期 运行 中的运行情况。这是代码片段。
Private Sub depBtn_Clicked(sender As Button, e As EventArgs)
If sender.BackColor = Color.Green Then
Dim depRow() As Data.DataRow
Dim id As String = sender.Name
depRow = DepartmentDataSet.Departments.Select("ID Like '" & id & "'")
sender.BackColor = Color.Red
Dim timerBtn As New DepartmentTimer(sender, depRow(0)("Duration"), depRow(0)("ID"))
Dim TimerDelegate As New System.Threading.TimerCallback(AddressOf TimerTask)
Dim TimerItem As New System.Threading.Timer(TimerDelegate, timerBtn, 0, 1000)
timerBtn.timerRef = TimerItem
End If
End Sub
Private Delegate Sub TimerTaskDelegate(ByVal obj As Object)
Private Sub TimerTask(ByVal obj As Object)
If Me.InvokeRequired() Then
Me.Invoke(New TimerTaskDelegate(AddressOf TimerTask), obj)
Else
Dim depTimer As DepartmentTimer = DirectCast(obj, DepartmentTimer)
depTimer.countDown()
If depTimer.duration = -1 Then
depTimer.finish()
depTimer.timerRef.Dispose()
End If
End If
End Sub
我已经阅读并体验到,如果我直接从定时器回调中更新 UI 线程,整个程序将会崩溃。所以我最终根据这里 http://tech.xster.net/tips/invoke-ui-changes-across-threads-on-vb-net/.
使用了一个委托
这是正确的做法还是我在做什么redundant/inefficient?
此外,当我处理 Timer 对象时。我将如何清理 DepartmentTimer class 实例 (timerBtn)?计时器 运行 结束后可以再次激活该按钮,所以我担心如果我不妥善处理它们,实例会堆积起来。
在此先感谢您的帮助。
因为除了立即调用回主线程外,您实际上并没有对计时器做任何事情,所以您最好使用 one System.Windows.Forms.Timer 并在同一个处理程序中更新它们。
类似于:
Public Class Form1
Private timers As New List(Of DepartmentTimer)
Private WithEvents Tmr As New System.Windows.Forms.Timer
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
Tmr.Interval = 1000
Tmr.Start()
End Sub
Private Sub depBtn_Clicked(sender As Button, e As EventArgs)
If sender.BackColor = Color.Green Then
Dim depRow() As Data.DataRow
Dim id As String = sender.Name
depRow = DepartmentDataSet.Departments.Select("ID Like '" & id & "'")
sender.BackColor = Color.Red
timers.Add(New DepartmentTimer(sender, depRow(0)("Duration"), depRow(0)("ID")))
End If
End Sub
Private Sub Tmr_Tick(sender As Object, e As EventArgs) Handles Tmr.Tick
For i As Integer = timers.Count - 1 To 0 Step -1
Dim depTimer As DepartmentTimer = timers(i)
depTimer.countDown()
If depTimer.duration = -1 Then
depTimer.finish()
timers.RemoveAt(i)
End If
Next
End Sub
End Class
我制作了一个小程序,允许针对每个单击的按钮进行单独的计时器倒计时。 (例如,点击按钮 1 将开始按钮 1 的倒计时,同时更新按钮本身的文本以反映剩余时间。)
我现在担心的是,我不确定我的程序在长期 运行 中的运行情况。这是代码片段。
Private Sub depBtn_Clicked(sender As Button, e As EventArgs)
If sender.BackColor = Color.Green Then
Dim depRow() As Data.DataRow
Dim id As String = sender.Name
depRow = DepartmentDataSet.Departments.Select("ID Like '" & id & "'")
sender.BackColor = Color.Red
Dim timerBtn As New DepartmentTimer(sender, depRow(0)("Duration"), depRow(0)("ID"))
Dim TimerDelegate As New System.Threading.TimerCallback(AddressOf TimerTask)
Dim TimerItem As New System.Threading.Timer(TimerDelegate, timerBtn, 0, 1000)
timerBtn.timerRef = TimerItem
End If
End Sub
Private Delegate Sub TimerTaskDelegate(ByVal obj As Object)
Private Sub TimerTask(ByVal obj As Object)
If Me.InvokeRequired() Then
Me.Invoke(New TimerTaskDelegate(AddressOf TimerTask), obj)
Else
Dim depTimer As DepartmentTimer = DirectCast(obj, DepartmentTimer)
depTimer.countDown()
If depTimer.duration = -1 Then
depTimer.finish()
depTimer.timerRef.Dispose()
End If
End If
End Sub
我已经阅读并体验到,如果我直接从定时器回调中更新 UI 线程,整个程序将会崩溃。所以我最终根据这里 http://tech.xster.net/tips/invoke-ui-changes-across-threads-on-vb-net/.
使用了一个委托这是正确的做法还是我在做什么redundant/inefficient? 此外,当我处理 Timer 对象时。我将如何清理 DepartmentTimer class 实例 (timerBtn)?计时器 运行 结束后可以再次激活该按钮,所以我担心如果我不妥善处理它们,实例会堆积起来。
在此先感谢您的帮助。
因为除了立即调用回主线程外,您实际上并没有对计时器做任何事情,所以您最好使用 one System.Windows.Forms.Timer 并在同一个处理程序中更新它们。
类似于:
Public Class Form1
Private timers As New List(Of DepartmentTimer)
Private WithEvents Tmr As New System.Windows.Forms.Timer
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
Tmr.Interval = 1000
Tmr.Start()
End Sub
Private Sub depBtn_Clicked(sender As Button, e As EventArgs)
If sender.BackColor = Color.Green Then
Dim depRow() As Data.DataRow
Dim id As String = sender.Name
depRow = DepartmentDataSet.Departments.Select("ID Like '" & id & "'")
sender.BackColor = Color.Red
timers.Add(New DepartmentTimer(sender, depRow(0)("Duration"), depRow(0)("ID")))
End If
End Sub
Private Sub Tmr_Tick(sender As Object, e As EventArgs) Handles Tmr.Tick
For i As Integer = timers.Count - 1 To 0 Step -1
Dim depTimer As DepartmentTimer = timers(i)
depTimer.countDown()
If depTimer.duration = -1 Then
depTimer.finish()
timers.RemoveAt(i)
End If
Next
End Sub
End Class