我做了一个小程序,允许单击每个按钮的单个计时器倒计时。 (例如,单击按钮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)?一旦计时器用完,该按钮可以再次激活,所以如果我不能正确处理它们,我担心这些情况会累积。
提前感谢您的帮助。
答案 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