VB线程计时器更新UI

时间:2015-01-21 06:50:19

标签: vb.net timer

我做了一个小程序,允许单击每个按钮的单个计时器倒计时。 (例如,单击按钮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/使用了一个代表。

这是一种正确的做法吗?还是我做了多余/低效的事情? 当我处理Timer对象时。我将如何清理DepartmentTimer类实例(timerBtn)?一旦计时器用完,该按钮可以再次激活,所以如果我不能正确处理它们,我担心这些情况会累积。

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

由于除了立即调用主UI线程之外,你实际上没有对Timer做任何事情,你也可以只使用 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