views:

62

answers:

3

I have written a thread which I've started using the start method but I'm not able to know when the thread has done executing the method and destroy the thread object.

_ProgressThread = New Thread(AddressOf ExecProc)
_ProgressThread.IsBackground = False
_ProgressThread.Start()

//the flow of execution should come here only after the thread has executed the method
//but its coming and executing this line after the thread has started.
 Me.MainInit()
_ProgressThread = Nothing

What is the best method. Please help. Also I want to call a method after the thread has done executing the mehtod.

+2  A: 

Firstly, setting a variable to Nothing doesn't destroy the object.

Secondly, if this is an instance variable but you don't need it after starting the thread, why keep it around at all? If it's a local variable, just let it fall out of scope.

Basically, it's not up to you to "destroy" the object - it's up to you to only keep a reference to it as long as you're interested in it.

If this doesn't help, please provide more details.

Jon Skeet
I want to execute a method after the thread has done executing the method, but the function is being called before the thread has completed execution.
Soham Dasgupta
@Soham: The simplest thing to do would be not to start "ExecProc" directly for the thread, but a method which calls `ExecProc` and then executes the other method.
Jon Skeet
+1  A: 

There are two (or more) possible ways. One is to use a ManualResetEvent as follows:

_Event = New ManualResetEvent(False); <-- Create event globally

Then, in your thread's start code:

_ProgressThread = New Thread(AddressOf ExecProc)
_ProgressThread.IsBackground = False
_ProgressThread.Start()

//the flow of execution should come here only after the thread has executed the method
//but its coming and executing this line after the thread has started.
_Event.WaitOne(); <-- This waits!
_Event.Close();   <-- This closes the event

Me.MainInit()
_ProgressThread = Nothing

In your thread method, you must call _Event.Set() before the method returns in all cases, otherwise your application will be blocked.

Another way would be to have to thread invoke a delegate when finished. The code that you want to execute after the thread is done (Me.MainInit()) would then go into the delegate method. This is actually quite elegant.

For example:

public delegate void ThreadDoneDelegate();

private void ExecProc()
{
    ThreadDoneDelegate del = new ThreadDoneDelegate(TheThreadIsDone);

    ... // Do work here

    this.Invoke(del);
}

private void TheThreadIsDone()
{
    ... // Continue with your work
}

Sorry, I do not speek VB fluently, so you'll have to convert this little C# snippet :-)

Thorsten Dittmar
Not a problem. I understand both worlds. Thanks anyway.
Soham Dasgupta
There is one problem I'm setting the value of a progress bar inside the thread method so every time i'm writing _event.set() before setting progress bar value it returning from the method and executing the maininit() method.
Soham Dasgupta
You do not call _event.Set() when updating the progress bar. You only call it before your thread method really exits (either because of errors or because its finished).
Thorsten Dittmar
But when I'm trying to update the progress bar UI, it ceases to increase and enters a deadlock. By the way I'm using a delegate to update the progressbar UI. Please help.
Soham Dasgupta
Of course - as your main thread is waiting for the sub-thread to end (_event.WaitOne()), calling this.Invoke to update the progress bar locks as well. If you want to update a progress bar, the second way I described would be better, as in that case the main thread is not waiting for anything to happen.
Thorsten Dittmar
+2  A: 

Hi.

If I understood it correctly, you want to wait for a thread to finish. This can be acomplished by joining the thread:

_ProgressThread = New Thread(AddressOf ExecProc)
_ProgressThread.IsBackground = False
_ProgressThread.Start()

// you can do parallel work here

// wait for the thread to finish
_ProgressThread.Join(); 
Vagaus
You're quite right but Thorsten Dittmar's answer is working correctly, the only problem is my progressbar UI is not updating and the application is entering a deadlock. Can u give me suggestion based on his answer. Thanks anyway.
Soham Dasgupta
It is kind of overkill (IMHO) to create an event when you can just use the thread obj. Anyway, I suppose you are trying to update the progressbar inside the thread right? If so, you need to marshall the call back to the UI thread using control.InvokeRequired /control.Invoke() members.For more details see http://msdn.microsoft.com/en-us/library/system.windows.forms.control.invokerequired(v=VS.100).aspx
Vagaus