Reputation: 357
In my windows forms application, I have to execute a method in a thread. The timing of method to execute depends upon a Tick Event. So, every 5 seconds, the Tick Event occurs and inside it checks for the time elapsed between last execution and now. If the elapsed time > 10 seconds, then only it executes the method creating a separate thread. But, the application should not execute the method, if the original thread has not completed its execution. In other words, the application executes the method in a thread and executes after 10 seconds once the thread completes its execution, not necessarily on the two ticks.
Now, the issue is: So, I need to place a logic inside the code, that stops the tick until the thread completes its execution.
I was trying to solve it by disabling the timer control when the thread starts and enable it again when the thread completes its execution, but seems like it is not working.
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
Upvotes: 0
Views: 391
Reputation: 357
Since the problem is related with MultiThreading, it needs to make thread thread safe calls to Windows Controls. Timer control (Timer1) was originally used inside Test() which was not thread safe. Thus, the issue was solved by making a thread safe call i.e by using BeginInvoke, which makes an asynchronous call to the another method (timeToggle(boolean)) that enables or disables timer.
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
Upvotes: 1