How does the main thread know when the work thread has finished?

K

Kueishiong Tu

I have a window form application. It requires to retrieve
data from a web site. Since the web request is very time
consuming, so I create a work thread to do the job.
How does the window main form (which is the main thread)
know when the work thread has finished the job so that
it can display the data received on the form? I do not
want to use a global variable since if the main form is
continuously checking for the global variable, it will
not be able to process the window UI events. I try to
raise an event when the work thread's job is done,
but how can the main thread detected this event?
..
 
T

Tobin Harris

Kueishiong Tu said:
I have a window form application. It requires to retrieve
data from a web site. Since the web request is very time
consuming, so I create a work thread to do the job.
How does the window main form (which is the main thread)
know when the work thread has finished the job so that
it can display the data received on the form? I do not
want to use a global variable since if the main form is
continuously checking for the global variable, it will
not be able to process the window UI events. I try to
raise an event when the work thread's job is done,
but how can the main thread detected this event?

The object that is performing an operation in the worker thread could raise
an event to indicate that it't progress is complete. Your form GUI could
subscribe to this event, and react when it knows the thread is complete. So,
it's not actually the main thread that is detecting this event, but rather
an object that is in the main thread. You just need to decide which object
(form etc) wants to know when the process is complete, and then register.
Eg.(off top of head)

private MyObj obj;

void buttonsGo_click( object s, EventArgs e ){
obj = new MyObj();
Thread t = new Thread( new ThreadStart( t.StartLongOperation() );
obj.OperationComplete += new EventHandler( this.handleComplete );
this.buttonGo.Enabled = false;
t.Run();
}

void handleComplete( object s, EventArgs e ){
if( InvokeRequired ){
BeginInvoke( new EventHandler( handleComplete );
}
this.buttonGo.Enabled = true;
}

Hope this helps

Tobin Harris
 
1

100

Hi Tobbin,
I just want to correct a bit the code snippet you provided. Your solution is
exactly what has to be done to handle this situation. Here are my
corrections. I commented out some of your code lines and put the corrected
ones along with explanation why I did so.
The object that is performing an operation in the worker thread could raise
an event to indicate that it't progress is complete. Your form GUI could
subscribe to this event, and react when it knows the thread is complete. So,
it's not actually the main thread that is detecting this event, but rather
an object that is in the main thread. You just need to decide which object
(form etc) wants to know when the process is complete, and then register.
Eg.(off top of head)

private MyObj obj;
void buttonsGo_click( object s, EventArgs e ){
obj = new MyObj();
//!!!!!Thread t = new Thread( new ThreadStart(
t.StartLongOperation() );
//Beside the Thread class doesn't have StartLongOperation member it
has to be MyObj's method. Otherwise it doesn't make sense
Thread t = new Thread( new ThreadStart( obj.StartLongOperation() );

//It might be good to have the worker thread a *background* thread
t.IsBackground = true;

obj.OperationComplete += new EventHandler( this.handleComplete );
this.buttonGo.Enabled = false;
//!!!! t.Run();
//Correct name of the method is Start
t.Start();
}

void handleComplete( object s, EventArgs e ){
if( InvokeRequired ){
//!!!!!BeginInvoke( new EventHandler( handleComplete );
//BeginInvoke will start the event handler in another thread
different than the main UI thread. What we want to do is to execute the
event handler in the UI thread context. We use Control.Invoke for this.
Invoke(new EventHandler(handleComplete));
}
this.buttonGo.Enabled = true;
}

B\rgds
100
 
T

Tobin Harris

Hi there,

Thanks for the corrections there! I have included them into a final version
below!

Cheers,

Tobin

private MyObj obj;

void buttonsGo_click( object s, EventArgs e ){
obj = new MyObj();
Thread t = new Thread( new ThreadStart( obj.StartLongOperation() );
t.IsBackground = true;
obj.OperationComplete += new EventHandler( this.handleComplete );
this.buttonGo.Enabled = false;
t.Start();
}

void handleComplete( object s, EventArgs e ){
if( InvokeRequired ){
Invoke( new EventHandler( handleComplete );
}
this.buttonGo.Enabled = true;
}
 

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

Top