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