Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vb.net VB线程计时器更新UI_Vb.net_Timer - Fatal编程技术网

Vb.net VB线程计时器更新UI

Vb.net VB线程计时器更新UI,vb.net,timer,Vb.net,Timer,我制作了一个小程序,允许为每个点击的按钮进行单独的计时器倒计时。e、 g.点击按钮1将开始按钮1的倒计时,同时更新按钮上的文本以反映剩余时间 我现在担心的是,我不确定我的程序从长远来看会有多好。下面是一段代码 Private Sub depBtn_Clicked(sender As Button, e As EventArgs) If sender.BackColor = Color.Green Then Dim depRow() As Data.DataRow

我制作了一个小程序,允许为每个点击的按钮进行单独的计时器倒计时。e、 g.点击按钮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线程,整个程序都会崩溃。因此,我最终按照这里的规定使用了一名代表

这是一种正确的方式,还是我在做一些多余/低效的事情? 也是在我处理计时器对象时。如何清理DepartmentTimer类实例timerBtn?这个按钮可以在计时器用完后再次激活,因此我担心如果我没有正确处理它们,实例会增加


提前感谢您的帮助。

由于您实际上没有使用计时器执行任何操作,只是立即调用回主UI线程,因此您最好只使用一个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

对此很抱歉,但这是否意味着所有按钮都将以相同的间隔倒计时?如果我在不同的时间单击按钮会怎么样?不会。它们都每秒更新一次,但在每个DepartmentTimer实例中都存储了自己的持续时间。此外,我还修复了示例中计时器的声明。试试看它是否有效。只需注释掉代码,就可以恢复。