Multithreading cancellation Methode

Hi All,
Lately I explore about multi threading,because there is a urgent need to implement this feature.I came up with a case of multi threading cancellation. There is two kind of multi threading we have.
1. threading in the program itself. ex.
Private Sub Worker_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles Worker.DoWork
Dim intI As Integer
Dim intJ As Integer
Dim intK As Integer
Dim counter As Integer
For intI = 1 To 20
For intJ = 1 To 20
For intK = 1 To 20
counter = counter + 1
'DO SOMETHING HERE
Next
Worker.ReportProgress(counter / 8000 * 100)
Next
Next
End Su
b
2. threading that branch to Database. ex.
Private Sub Worker_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles Worker.DoWork
objDataTable=<Query to a very huge database)
End Su
b
We want a button to cancel the thread. I read we can use cancelasync and the check cancellationpending flag in the doWork. But where should put this thing in the both case
Please help.
Thank you very much.
Regards,
Freddy halim


Answer this question

Multithreading cancellation Methode

  • RookieDBA

    Hi Freddy

    I am not familiar with the background worker class, but you seem to be suggesting that the worker thread is tied up in the database and therefore not actually 'running'.  If this is the case, I'd recommend you control the worker thread yourself and terminate it manually.

    You can spawn a worker thread yourself, and you can abort the thread manually which will raise an exception in the worker method (ThreadAbortException) that you can trap.  Note that the operation of closing a thread is not inherently synchronous, hence the call to the Join method. 

    It may not be the exact pattern you need but hopefully it is something that you may be able to consider/tweak.

    Private wt As Threading.Thread

    Private syncRoot As New Object

    Sub StartWork()

    SyncLock syncRoot

    wt = New Threading.Thread(AddressOf Me.DoWork)

    wt.IsBackground = True

    wt.Start()

    End SyncLock

    End Sub

    Sub StopIfWorking()

    SyncLock syncRoot

    If wt IsNot Nothing Then

    wt.Abort() : Threading.Thread.CurrentThread.Join(timeout)

    wt = Nothing

    End If

    End SyncLock

    End Sub

    Sub DoWork()

    Try

    Catch ex As Threading.ThreadAbortException

    End Try

    End Sub

    Richard


  • karthik asok

    You could put an IF statement where it could check fairly often whether there's a cancelation pending. Maybe something like:

    For intK = 1 To 20
    If Worker.CancellationPending = True then
    e.Cancel = True
    SomeBooleanVariableForCancel = True 'maybe use a boolean so the other loops know the action's been cancelled
    e.Cancel = True
    Exit For
    Else
    counter = counter + 1
    'DO SOMETHING HERE
    End If
    Next
    Worker.ReportProgress(counter / 8000 * 100)

    In the RunWorkerCompleted routine, you can then check the e.Cancelled value to see if you had set it in the DoWork loop, and if it's set, process the cancelation accordingly.

    I haven't played with connecting to a database, but my guess is that you could do something similar:

    If Worker.CancellationPending = True then
    'Do the cancel stuff
    Else
    objDataTable = (Query to the huge database)
    End If

    Your main thread that started the background worker can trigger off the cancel button click to generate the BackgroundWorker.CancelAsync() that sets the CancellationPending flag to true.


  • Sundararajan

    Dear Richard,I have try your methods, and it works like charming.Thank you very much.I do some experiment with your method with my second case.Your method can cancel a long thread that has been branch to database too.Superb....Regards,Freddy
  • rKarthik

    dear Richard,
    Yeah, I try your solution it is work for my first case.
    But still i got problem report to progress bar since the thread is not interference with other ( thread safe).Here is my problem.
    Private Sub DoWork1()
    Try
    Dim objConnection As OleDbConnection
    Dim objCommand As OleDbCommand
    Dim intI As Integer
    Dim intJ As Integer
    Dim intK As Integer
    Dim counter As Integer
    objConnection = New OleDbConnection(vConnString)
    objConnection.Open()
    objCommand = objConnection.CreateCommand
    For intI = 1 To 20
    For intJ = 1 To 20
    For intK = 1 To 20
    counter = counter + 1
    Try
    objCommand.CommandText = "INSERT INTO tblTest(col1,col2,col3) VALUES " & _
    "('" & intI & "','" & intJ & "','" & intK & "')"
    objCommand.ExecuteNonQuery()
    Catch ex As Exception
    MessageBox.Show("Thread is closing")
    End Try
    Next
    ProgressBar1.Value = counter / 8000 * 100 <==== this is my error
    Next
    Next
    objConnection.Close()
    Catch ex As Threading.ThreadAbortException
    MessageBox.Show(ex.ToString)
    End Try
    End Sub

    Are there any solution
    Still the second case has no solution.If the thread query to a huge DB.How to cancel the thread.
    Are there any suggestion

    Dears,
    Freddy




  • Glyn Darkin

    Hi Freddy

    I'm not 100% sure what you are asking. Hopefully, some of the following will prove relevant and make sense to you.

    DoWork1 is presumably running on a background thread. This means that it cannot interact directly with the progress bar as it is not the thread that created that control. What you need to do, is update the progress bar through another method and call that method via a delegate that is passed to the Invoke method of the progress control. Something like this should help ....

    private delegate sub updateprogressbardelegate (byval value as double)

    private sub updateprogressbar(byval value as double)

    if progressbar.invokerequired then

    progressbar.invoke(new updateprogressbardelegate(addressof updateprogressbar), value)

    else : progressbar.value = value

    end if

    end sub

    Simply replace the call to the setter ProgressBar1.Value = XXX to call the update progress bar method instead.

    If the above is not what you were looking for, please let me know and I will try to help.

    Richard


  • Kapoulkine Arseny

    I have done your cancelation style in my first case, but still i got the thread is finished.Why the thread is not cancelled if we do "e.cancel = true"For the second case I observe the other system we used, that is SAP.SAP provide thread to DB cancellation via GUID(SM50).Is there anyone who know this in VS2005 area Thank you
  • Multithreading cancellation Methode