non blocking wait in C#

  • Thread starter Thread starter Dave Hardy
  • Start date Start date
D

Dave Hardy

I have thread t1 . It spawns thread t2. I want to wait in thread t1
until the execution of thread t2 in completed. Bu t I do not want it to
be a blocking wait since I want thread t1 to be responsive to WM_PAINT
messages. I know how to do it in VC++ , but I have no idea how it can be
done in C#. Please help!!!

Regards,
Dave
 
Hi Dave,

You might signalize from t2 to t1 in some way, like calling a method or
raising an ManualEvent perhaps.
 
Instead of explicitly spawining a thread, wrap your thread's entry point
method in a delegate and call BeginInvoke(), passing another callback
delegate which is to be called when your task completes, e.g.

public void StartIt()
{
new MyDelegate(threadStart).BeginInvoke(new AsynchCallback(myCallback),
null);
}

private void threadStart()
{
// Do your work in here
}

private void myCallback(IAsynchResult ar)
{
// To update the UI, marshal the call to the UI thread
this.Invoke(new MethodInvoker(updateUI));
}

private void updateUI()
{
this.someTextBox.Text = "Thread is done!";
}

The main thing to remember is that your callback function will be invoked on
the same thread as performed the long processing work. So, if you want to
update your UI, you'll need to use the form's Invoke method to marshal the
call to the UI thread.

Hope that helps -
Ken
 
Whoops -- left out the call to EndInvoke() within the myCallback() function.
You should call EndInvoke() on the delegate to ensure .NET cleans up
properly after it, e.g.

private void myCallback(IAsynchResult ar)
{
MyDelegate dlg = (MyDelegate) ((AsynchResult)ar).AsynchDelegate;
dlg.EndInvoke(ar);

// To update the UI, marshal the call to the UI thread
this.Invoke(new MethodInvoker(updateUI));
}


Ken
 
Hi Ken...
Thanks for the suggestion. But, if the callback is being called in
the context of thread t2, it does not solve my problem.t2 is my worker
thread.t1 is a UI thread. After completion of the processing in t2, I
want to display some UI in t1. I do not want to display UI in callback
if it is being invoked in the context of t2. I want to keep all the UI
in thread t1.

Any other suggestion?

Regards,
Dave
 
private void StartWorkigThread
{
//this is execute from thread 1
System.Threading.ThreadPool.QueueUserWorkItem(new
System.Threading.WaitCallback(this.StartWorkingThread));

//thread 1 is now free to execute all the event like repait or button
pushing .... or execute others function

}

private void StartWorkingThread(object state)
{
//this is exectute from thread 2
.........

this.Invoke(new System.Threading.ThreadStart(this.WorkingThreadIsDone));
//thread 2 go back in thread pool
}

private void WorkingThreadIsDone()
{
//this is execute from thread 1
....
}
 
Absolutely, you need to keep all of the UI code in thread t1. This is why,
in your callback, you use the form's Invoke() method. This method allows you
to invoke a method on the UI thread instead of the thread on which the
callback occurs. So, in the code:

private void myCallback(IAsynchResult ar)
{
// To update the UI, marshal the call to the UI thread
this.Invoke(new MethodInvoker(updateUI));
}

private void updateUI()
{
this.someTextBox.Text = "Thread is done!";
}

The function myCallback() is running on thread t2, but by calling
this.Invoke(...), the function updateUI will run on thread t1.

Ken
 
Dave Hardy said:
I have thread t1 . It spawns thread t2. I want to wait in thread t1
until the execution of thread t2 in completed. Bu t I do not want it to
be a blocking wait since I want thread t1 to be responsive to WM_PAINT
messages. I know how to do it in VC++ , but I have no idea how it can be
done in C#. Please help!!!

It sounds to me like you shouldn't really be waiting in t1 at all - you
should instead be subscribing to an event in the calculation of t2 to
let you know when the execution has completed, using Control.Invoke to
"get back" to t1.

See http://www.pobox.com/~skeet/csharp/threads
 
Back
Top