How do I know when a thread has finished?

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Hello I wish to execute some code when and only when a thread has completed
like so

thrRestore = New Thread(AddressOf RestoreDb)
thrRestore.IsBackground = True
thrRestore.Start()

??? I only want the next bit to run when thrRestore is complete how do i
know
while thrRestore.isalive

end while 'this doesn't work, it just loops around forever.

If BlnDatabaseChanged Then
Call ProjectNameSpace.mdiClient.LoadActiveItems(False)
End If

Thanx in advance
Robert
 
Robert Smith said:
Hello I wish to execute some code when and only when a thread has completed
like so

thrRestore = New Thread(AddressOf RestoreDb)
thrRestore.IsBackground = True
thrRestore.Start()

??? I only want the next bit to run when thrRestore is complete how do i
know
while thrRestore.isalive

end while 'this doesn't work, it just loops around forever.

If BlnDatabaseChanged Then
Call ProjectNameSpace.mdiClient.LoadActiveItems(False)
End If

Thanx in advance
Robert

Do you want thrRestore.join() ?
Why would you want to start a new thread & then not use the current thread
to actually process anything ?
 
Robert,

Raise an event at the end of the thread and catch that in your main thread.
Have a look or try this sample (I changed it a little bit in this text so
there can be errors).

\\\needs on form 1 one button and a textbox
Private WithEvents frm1 As Form2
Private Delegate Sub Frm1Handler(ByVal message As String)
Private MyThread As System.Threading.Thread
Private Sub Form1_Load(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Dim timer1 As New System.Windows.Forms.Timer
AddHandler timer1.Tick, AddressOf mytimer1
TextBox1.Text = "0"
timer1.Enabled = True
timer1.Interval = 400
Dim timer2 As New System.Windows.Forms.Timer
End Sub
Private Sub mytimer1(ByVal sender As Object, _
ByVal e As System.EventArgs)
TextBox1.Text = (CInt(TextBox1.Text) + 1).ToString
DirectCast(sender, System.Windows.Forms.Timer).Enabled = True
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
frm1 = New Form2
frm1.itstop = Me.Top
frm1.itsleft = Me.Left + 200
AddHandler frm1.ready, AddressOf Frm1Ready
frm1.Text = "Extra thread"
MyThread = New System.Threading.Thread(AddressOf frm1.Show)
MyThread.Start()
End Sub
Private Sub Frm1Ready(ByVal message As String)
Me.BeginInvoke(New Frm1Handler(AddressOf Frm1HandlerSub), New
Object() {message})
End Sub
Private Sub Frm1HandlerSub(ByVal message As String)
TextBox2.Text = message
frm1.Close()
MyThread.Abort()
End Sub
Private Sub Form1_Closing(ByVal sender As Object, _
ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
MyThread.Abort()
End Sub
///
\\\Needs a form2 with one textbox
Friend Event ready(ByVal message As String)
Friend itstop As Integer
Friend itsleft As Integer
Private Sub Form2_Activated(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles MyBase.Activated
Me.Left = itsleft
Me.Top = itstop
Me.BringToFront()
Dim timenext As DateTime = Now.Add(TimeSpan.FromSeconds(10))
Do While timenext > Now
TextBox1.Text = Now.TimeOfDay.ToString
Application.DoEvents() 'to show the time
Threading.Thread.Sleep(50)
Me.Opacity -= 0.004
Loop
RaiseEvent ready(Now.TimeOfDay.ToString)
End Sub
Private Sub Form2_Closing(ByVal sender As Object, ByVal _
e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
e.Cancel = True
End Sub
///
I hope this helps a little bit?

Cor
 
Hi Jb,
I don't want to process the process the next bit in the same thread
because I get errors saying cannot alter controls that have been created in
another thread, other places where this code is called outside of a thread do
not get this error.
 
From MSDN

"Controls in Windows Forms are bound to a specific thread and are not thread
safe. Therefore, if you are calling a control's method from a different
thread, you must use one of the control's invoke methods to marshal the call
to the proper thread. "
 
Cor,
Noce example, thanks for putting it on this ng.

I changed some small things and added comments. Works great!
Whats the difference between using BeginInvoke and just calling the method,
frm2HandlerSub, directly????



============FORM1 BELOW
'Project needs two forms
'Form 1 needs two textboxes and a button.
'Form2 needs one text box
'Raises an event at the end of the thread and catchs that in the main
thread.
'The Delegate class is not a delegate type; it is used to derive delegate
types, like frm2Handler.
Private Delegate Sub frm2Handler(ByVal message As String)
Private WithEvents frm2 As Form2
Private MyThread As System.Threading.Thread
Private Sub Form1_Load(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Dim timer1 As New System.Windows.Forms.Timer
AddHandler timer1.Tick, AddressOf mytimer1
TextBox1.Text = "0"
TextBox2.Text = ""
timer1.Enabled = True
timer1.Interval = 400
Dim timer2 As New System.Windows.Forms.Timer
End Sub
Private Sub mytimer1(ByVal sender As Object, _
ByVal e As System.EventArgs)
TextBox1.Text = (CInt(TextBox1.Text) + 1).ToString
DirectCast(sender, System.Windows.Forms.Timer).Enabled = True
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
TextBox1.Text = "0"
TextBox2.Text = ""
frm2 = New Form2
frm2.itstop = Me.Top
frm2.itsleft = Me.Left + 200
AddHandler frm2.ready, AddressOf frm2Ready
frm2.Text = "Extra thread"
MyThread = New System.Threading.Thread(AddressOf frm2.Show)
MyThread.Start()
End Sub
Private Sub frm2Ready(ByVal message As String)
'The frm2 Ready event returns the time of day in message
'The delegate ,frm2Handler,is called asynchronously, and this method returns
immediately.
'You can call this method from any thread, even the thread that owns the
control's handle.
'frm2Handler is a type so New frm2Handler(AddressOf frm2HandlerSub) runs the
type's constructor
'and return an instance of the type
'Second BeginInvoke argument is an array of objects to pass as arguments to
the given method.
'This array has one member, "message"
Me.BeginInvoke(New frm2Handler(AddressOf frm2HandlerSub), New Object()
{message})
End Sub
Private Sub frm2HandlerSub(ByVal message As String)
TextBox2.Text = message
frm2.Close()
MyThread.Abort()
End Sub
Private Sub Form1_Closing(ByVal sender As Object, _
ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
MyThread.Abort()
End Sub
End Class
============FORM2 BELOW
Friend Event ready(ByVal message As String)
Friend itstop As Integer
Friend itsleft As Integer
Private Sub Form2_Activated(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles MyBase.Activated
Me.Left = itsleft
Me.Top = itstop
Me.BringToFront()
'Count down 10 seconds
Dim timenext As DateTime = Now.Add(TimeSpan.FromSeconds(10))
Do While timenext > Now
TextBox1.Text = Now.TimeOfDay.ToString 'Show time every 50 milliseconds
Application.DoEvents() 'to show the time
Threading.Thread.Sleep(50) 'pause for 50 milliseconds
Me.Opacity -= 0.004
Loop
RaiseEvent ready(Now.TimeOfDay.ToString) 'Raise "ready" event
End Sub
Private Sub Form2_Closing(ByVal sender As Object, ByVal _
e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
e.Cancel = True
End Sub
End Class
 
Robert Smith said:
Hello I wish to execute some code when and only when a
thread has completed like so

Take a look at the 'IAsyncResult' interface in the documentation.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top