sagar pant
sagar pant

Reputation: 357

Need help on Threading with WIndows Form Control in VB.Net

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

Answers (1)

sagar pant
sagar pant

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

Related Questions