Click here to Skip to main content
15,885,366 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
i'm using Synchronizing Threads but when the thread is starting i'm not able to click on anthing on my application... but i need to do some work on the app even if the thread timer is on so how can i do that?

note that i'm using vb.net on vs 2010

here is my code:

VB
Private Shared thread As New System.Threading.AutoResetEvent(False) 

Private Sub start_btn_Click(sender As System.Object, e As System.EventArgs) Handles start_btn.Click
    StartTask()
End Sub

Sub StartTask()
    Dim Tpool As System.Threading.ThreadPool
    Dim arg As String = "SomeArg"
    ThreadPool.QueueUserWorkItem(New System.Threading.WaitCallback( _
       AddressOf Task), arg)  ' Queue a task.
    thread.WaitOne() ' Wait for the thread to call Set.
    writeMsg("Thread is done. at ", "list_rpt")
    StartTask()
End Sub

Sub Task(ByVal Arg As Object)
    writeMsg("Thread is starting at ", "list_rpt")
    System.Threading.Thread.Sleep(4000) ' Wait 4 seconds.
    DoWork()
End Sub

Public Sub DoWork()
    MTProcessTable = selectMtProcess()
    mtCount = MTProcessTable.Rows.Count
    writeMsg(mtCount & " rows selected at ", "list_rpt")

    For Each row As DataRow In MTProcessTable.Rows
        process = New Process_class
        process.id = row("mt_id")
        process.mo = row("mt_mo")
        process.mt = row("mt_mt")
        process.datain = row("mt_datain")

        keyid = validateKey(process.datain)
        MOTable = selectMO(process.mo, process.mt)
        moRowNb = MOTable.Rows.Count()
        MO = New MO_class
        If moRowNb <> 0 Then
            MOrow = MOTable.Rows(0)
            MO.newuser = MOrow("newuser")
            MO.sim_id = MOrow("sim_id")
        End If
        Try
            Select Case keyid
                Case 1
                    If moRowNb = 0 Then
                        If insertMO(process.mo, process.mt) Then
                            writeMsg("1 MO inserted/updated at ", "rpt_txt")
                            message = msgTable.Rows(0)(1).ToString()
                            MsgBox(message)
                        Else
                            writeMsg("1 MO could not be inserted at ", "rpt_txt")
                         End If
                   End if
                Case 2
                    If moRowNb = 0 Then
                        writeMsg("1 process with MO not active and datain 'yes' at ", "rpt_txt")
                        message = msgTable.Rows(7)(1).ToString()
                        MsgBox(message)
                    End if
        Catch ex As Exception
            logFile("executeTimer ----" & ex.Message)
            updateProcessed(process.id, ex.Message, 10)
        Finally
            updateProcessed(process.id, message, 1)
        End Try
    Next row
    thread.Set()
End Sub
Posted
Updated 5-Sep-13 22:01pm
v2

1 solution

Don't do things like this:
VB
ThreadPool.QueueUserWorkItem(New System.Threading.WaitCallback( _
   AddressOf Task), arg)  ' Queue a task.
thread.WaitOne() ' Wait for the thread to call Set.

To spawn a new thread and then immediately wait for that thread to finish on the thread that started it is the same as not threading it at all. You might as well do all of the work in Task in the button click event.

You want the thread to do it's work and then notify back to the thread that started it (possibly with status updates being notified back as the work is being done).

What you're doing in your application is a WaitOne on the UI thread, if you do that your UI will lock until the event is notified, this is bad.

If you're just starting out with multithreading your application, look into using the BackgroundWorker, that comes with events that you can hook into to do things like status updates and report when task is completed.

Something like this might work for you:
Imports System.Threading
Imports System.ComponentModel

Public Class Form1

    Private Sub startButton_Click(sender As System.Object, e As System.EventArgs) Handles startButton.Click
        Dim worker As New BackgroundWorker()

        worker.WorkerSupportsCancellation = True
        worker.WorkerReportsProgress = True

        AddHandler worker.DoWork, AddressOf MyLongRunningOperation
        AddHandler worker.ProgressChanged, AddressOf MyProgressUpdate
        AddHandler worker.RunWorkerCompleted, AddressOf MyWorkHereIsDone

        worker.RunWorkerAsync()
    End Sub

    Sub MyLongRunningOperation(sender As Object, e As DoWorkEventArgs)
        Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)

        For i = 0 To 10
            If worker.CancellationPending Then
                e.Cancel = True
                Exit For
            End If
            ' Do your work
            Thread.Sleep(1000)
            worker.ReportProgress(i * 10)
        Next
    End Sub

    Private Sub MyProgressUpdate(ByVal sender As Object, ByVal e As ProgressChangedEventArgs)
        progressBar.Value = e.ProgressPercentage
        statusText.Text = e.ProgressPercentage & "% complete"
    End Sub

    Private Sub MyWorkHereIsDone(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)
        If e.Cancelled = True Then
            completedText.Text = "Operation was cancelled!"
        ElseIf e.Error IsNot Nothing Then
            completedText.Text = "Operation failed: " & e.Error.Message
        Else
            completedText.Text = "I am all done!"
        End If
    End Sub

End Class


It relies on progressBar, statusText and completedText being on your form. I haven't wired up a cancel button but that should be self explanatory I think.

Hope this helps,
Fredrik
 
Share this answer
 
v2
Comments
Jocelyne El Khoury 6-Sep-13 6:01am    
okey i fixed this error but now i can't stop my thread ! can you please tell me how can i stop it? note that i need to call the thread everytime the for loop is completed but when i click on the button stop i need to stop the thread
Fredrik Bornander 6-Sep-13 6:19am    
I've adorned my answer with a working example. Let me know if this helps you.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900