在我的Windows窗体应用程序中,我必须在一个线程中执行一个方法。执行方法的时间取决于Tick事件。因此,每隔5秒钟,Tick事件就会发生,并在里面检查上次执行和现在之间经过的时间。如果经过的时间> 10秒,然后只执行创建单独线程的方法。但是,如果原始线程尚未完成其执行,则应用程序不应执行该方法。换句话说,应用程序在线程中执行该方法,并在线程完成执行后10秒后执行,而不一定在两个刻度上。
现在,问题是: 所以,我需要在代码中放置一个逻辑,停止勾选直到线程完成执行。
我试图通过在线程启动时禁用定时器控件来解决它,并在线程完成执行时再次启用它,但看起来它不起作用。
Public Class Form1
Private lastRunDateTime As DateTime = #1/1/1900#
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Timer1.Interval = 5000
Timer1.Enabled = True
End Sub
'This method takes more than 5 seconds
Private Sub test()
For value As Integer = 0 To 10000
Console.WriteLine(value)
Next
'Timer1.Enabled = True
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
If DateDiff(DateInterval.Second, lastRunDateTime, Now) > 10 Then
'Timer1.Enabled = False
lastRunDateTime = Now
Dim th = New Threading.Thread(Sub() test())
th.Start()
End If
End Sub
End Class
答案 0 :(得分:1)
由于问题与MultiThreading有关,因此需要对Windows控件进行线程线程安全调用。定时器控制(Timer1)最初在Test()中使用,它不是线程安全的。因此,通过进行线程安全调用解决了这个问题,即使用BeginInvoke,它对另一个启用或禁用计时器的方法(timeToggle(boolean))进行异步调用。
Public Class Form1
Private lastRunDateTime As DateTime = #1/1/1900#
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Timer1.Interval = 5000
Timer1.Enabled = True
End Sub
'*********Delegate Added********************************
Private Delegate Sub _toggleDelegate(start As Boolean)
'*********************************************************
'This method takes more than 5 seconds
Private Sub test()
For value As Integer = 0 To 10000
Console.WriteLine(value)
Next
'Timer1.Enabled = True
'*********New Addition*************
Me.BeginInvoke(New _toggleDelegate(AddressOf toggleTimer), True)
'**********************
End Sub
'********New Method Added**************
Private Sub toggleTimer(start As Boolean)
Timer1.Enabled = start
End Sub
'*************************************
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
If DateDiff(DateInterval.Second, lastRunDateTime, Now) > 10 Then
'Me.BeginInvoke(New _toggleDelegate(AddressOf toggleTimer), False)
'**********uncommented now or can the statement above*******
Timer1.Enabled = False
'**********************
lastRunDateTime = Now
Dim th = New Threading.Thread(Sub() test())
th.Start()
End If
End Sub
End Class