Using delegates between main/sub threads

P

Pixel.to.life

Dear All,

Here is a problem I am facing (it might be too simple, but then I
admit I am not a Guru:)

I have a main thread, in managed C++, that deals with displaying a
form and some controls.

I invoke another thread for some processing from this thread, so
basically the main thread is waiting on the sub thread.

Now the sub-thread has to keep posting its progress to the main
thread. I have a delegate mechanism for that. So using mutex, I update
the progress variable in the sub-thread's scope, and then invoke the
main thread's delegate method to display the progress.

The problem is just when the delegate is invoked. Control switches
form sub to main thread. But main thread is already waiting for the
sub thread to finish, so it deadlocks right there.

Any ideas/suggestions? The solution seems simple, just that I dont get
it yet.

Thanks!
 
J

Jon Skeet [C# MVP]

Pixel.to.life said:
Here is a problem I am facing (it might be too simple, but then I
admit I am not a Guru:)

I have a main thread, in managed C++, that deals with displaying a
form and some controls.

I invoke another thread for some processing from this thread, so
basically the main thread is waiting on the sub thread.

That's your problem - don't make the main thread wait. The point of
using other threads to do work in a UI application is to avoid the UI
locking up. You need to keep the UI event loop free to handle things
like screen refreshes.
 
P

Pixel.to.life

That's your problem - don't make the main thread wait. The point of
using other threads to do work in a UI application is to avoid the UI
locking up. You need to keep the UI event loop free to handle things
like screen refreshes.

--
Jon Skeet - <[email protected]>
Web site:http://www.pobox.com/~skeet 
Blog:http://www.msmvps.com/jon.skeet
C# in Depth:http://csharpindepth.com

Thanks Jon.

I realised it after I posted.

Fow now I use WaitForSingleThread(..) API to wait on the sub thread.
Whats the alternative so the sub thread processing can be done
asynchronously?

I am looking at MsgWaitForMultipleObjects(..) instead to see if I can
get status right there.

Sorry I am a novice to multithreading with GUI.
 
P

Pixel.to.life

That's your problem - don't make the main thread wait. The point of
using other threads to do work in a UI application is to avoid the UI
locking up. You need to keep the UI event loop free to handle things
like screen refreshes.

--
Jon Skeet - <[email protected]>
Web site:http://www.pobox.com/~skeet 
Blog:http://www.msmvps.com/jon.skeet
C# in Depth:http://csharpindepth.com

Also, I need to wait for the sub thread because the main thread has to
do some consilidation once the sub thread is done. If I remove the
WaitForSingleThread(...) call, how do I know the subthread is done?

Thanks.
 
J

Jon Skeet [C# MVP]

Pixel.to.life said:
Also, I need to wait for the sub thread because the main thread has to
do some consilidation once the sub thread is done. If I remove the
WaitForSingleThread(...) call, how do I know the subthread is done?

Get the subthread to post back into the main thread, just as it would
to update the UI - using Control.Invoke or Control.BeginInvoke.
 
J

Jon Skeet [C# MVP]

Pixel.to.life said:
Fow now I use WaitForSingleThread(..) API to wait on the sub thread.
Whats the alternative so the sub thread processing can be done
asynchronously?

Just don't wait at all :) If you need to do something when the other
thread's finished, get it to tell you with a call to
Control.Invoke/BeginInvoke.
I am looking at MsgWaitForMultipleObjects(..) instead to see if I can
get status right there.

Sorry I am a novice to multithreading with GUI.

That's okay - it's a tricky topic. I have a brief introduction to
threading here:

http://pobox.com/~skeet/csharp/threads
 
P

Pixel.to.life

Just don't wait at all :) If you need to do something when the other
thread's finished, get it to tell you with a call to
Control.Invoke/BeginInvoke.



That's okay - it's a tricky topic. I have a brief introduction to
threading here:

http://pobox.com/~skeet/csharp/threads

--
Jon Skeet - <[email protected]>
Web site:http://www.pobox.com/~skeet 
Blog:http://www.msmvps.com/jon.skeet
C# in Depth:http://csharpindepth.com


Thanks a lot, Jon. I finally figured out how to do it. I dont wait,
but let the sub thread work async-ly.. and have it post a message
BeginInvoke() when its done.

I noticed that BeginInvoke() isnt as powerful in having UI refresh its
controls.. and when I use Invoke(), its the same problem as before.
Its blocking kind of.

Thanks again!
 
J

Jon Skeet [C# MVP]

I noticed that BeginInvoke() isnt as powerful in having UI refresh its
controls..

What exactly do you mean?
and when I use Invoke(), its the same problem as before.
Its blocking kind of.

No "kind of" about it - it blocks until the delegate has executed in
the UI thread.
 
J

Jon Skeet [C# MVP]

Pixel.to.life said:
Ok I correct myself: Invoke() is blocking exactly until the UI updates
itself.

I should just apologise for the tone of my previous message - it wasn't
*meant* to sound patronising or impatient, but I suspect it came out
that way. Amazingly enough, I couldn't find the blocking nature on the
Control.Invoke documentation page. It's probably there somewhere,
but...
 
J

Jon Skeet [C# MVP]

On May 8, 7:09 am, "Peter Duniho" <[email protected]>
wrote:

I don't think that there _is_ an explicit statement as to the
blocking/synchronous nature of Control.Invoke(), but neither do I think
it's really necessary.

While I agree with your logic suggesting it's not *necessary*, I do
think it would be *useful* - particularly if it also pointed out the
option of using BeginInvoke() for a non-blocking form.

Will suggest it to the MSDN team when I have time...

Jon
 
B

Ben Voigt [C++ MVP]

It seems to me that it's asynchronous operations that would warrant
calling out the specific nature of a method in the docs. IMHO, it's
reasonable to assume that a method is synchronous unless stated
otherwise. In that sense, the docs for Control.Invoke() have no need

Rather, it's reasonable to assume that a method is executed on the same
thread unless stated otherwise. Synchronization comes with that behavior.
Once you take away the same thread assumption then synchronization should be
called out explicitly.
for a specific statement that it's synchronous, blocking until the
delegate is done. It's implied, because it's always implied that a
method won't return until whatever that method does is done.

You just pointed out that this frequently isn't the case (updating internal
UI state but the screen isn't updated until Windows sends a WM_PAINT).
 
B

Ben Voigt [C++ MVP]

I have no idea what you mean here. If you use Invoke() to call a
method that updates internal UI state, then when Invoke() returns,
you can be sure that what that method does -- updating internal UI
state -- is done. If the method doesn't send a WM_PAINT, then the
question of when the screen is updated or when a WM_PAINT message
might be sent is irrelevant. That's not what the method being invoked
does.
Don't confuse what a method _does_ with what later implications that
activity might have. For example, the question of when a WM_PAINT
message is sent is independent of when a method that updates internal
UI state is done, and this is true whether you call that method
directly within the correct thread, or call it indirectly from
another thread using Invoke().

But by this definition, BeginInvoke is also synchronous. It does not do
what the documentation says ("Executes a delegate asynchronously"), it posts
a request into a queue corresponding to the UI thread, then returns. The
future execution of the delegate identified in that request is merely a
"later implication of that activity".
 

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