Gmail Calendar Documents Web Reader more »
Help | Sign in
Google Groups Home
Delegate BeginInvoke and ManualResetEvent.WaitOne()
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  6 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Alphapage  
View profile  
 More options Feb 11 2008, 12:56 pm
Newsgroups: microsoft.public.dotnet.framework
From: Alphapage <Alphap...@discussions.microsoft.com>
Date: Mon, 11 Feb 2008 09:56:01 -0800
Local: Mon, Feb 11 2008 12:56 pm
Subject: Delegate BeginInvoke and ManualResetEvent.WaitOne()
Hello,

Here is an example:

ManualResetEvent waiter;
delegate DoWorkDelegate;

void DoWork()
{
       waiter.WaitOne();

}

void SubMethodnvoke()
{
DoWorkDelegate.BeginInvoke(DoWork);

}

I do something like this when I open Submethods in my app.
I want to know how many submethods I can open.
I think this asynchronous delegate works as a ThreadPool, so if I open more
than the pool threads limit (ie 25 threads by default) I will probably have
some troubles.

In fact, I don't know how it works in background. In the msdn documentation,
ManualResetEvent.WaitOne() blocks the Thread until it receives a signal. But
I hope this is not really the case and the Thread is reused in background to
run some other jobs because if I have more than 25 waiting threads in the
queue my app is dead.
Is ManualResetEvent.WaitOne() really blocking a Thread or is there any job
in the ThreadPool to let those waiting Threads not block all others in the
queue ?

Thanks in advance for your help.


    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Peter Duniho  
View profile  
 More options Feb 11 2008, 1:25 pm
Newsgroups: microsoft.public.dotnet.framework
From: "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>
Date: Mon, 11 Feb 2008 10:25:29 -0800
Local: Mon, Feb 11 2008 1:25 pm
Subject: Re: Delegate BeginInvoke and ManualResetEvent.WaitOne()
On Mon, 11 Feb 2008 09:56:01 -0800, Alphapage  

<Alphap...@discussions.microsoft.com> wrote:
> Here is an example:

> ManualResetEvent waiter;
> delegate DoWorkDelegate;

> void DoWork()
> {
>        waiter.WaitOne();
> }

Don't do that.

> void SubMethodnvoke()
> {
> DoWorkDelegate.BeginInvoke(DoWork);
> }

> I do something like this when I open Submethods in my app.
> I want to know how many submethods I can open.
> I think this asynchronous delegate works as a ThreadPool, so if I open  
> more
> than the pool threads limit (ie 25 threads by default) I will probably  
> have
> some troubles.

Yes.  Given the above, you certainly could have trouble.

> In fact, I don't know how it works in background. In the msdn  
> documentation,
> ManualResetEvent.WaitOne() blocks the Thread until it receives a signal.

That's correct.

> But
> I hope this is not really the case and the Thread is reused in  
> background to
> run some other jobs because if I have more than 25 waiting threads in the
> queue my app is dead.

Unfortunately, hoping for something doesn't make it true.  .NET does not  
release a thread pool thread back to the pool just because your code has  
called WaitHandle.WaitOne().  The thread will indeed simply block and  
remain unavailable for further processing.

The thread pool is significantly larger than 25 threads in .NET 2.0 and  
later.  But, you are right...there is still the potential for a problem.  
You'd just need a lot more waiting threads to run into it with more recent  
versions of .NET.

In general, it's not a good idea to block in a thread pool thread.  Thread  
pool threads are for reasonably short tasks that can be completed straight  
through.  If you need a thread that can block for an arbitrarily long  
amount of time, create a new thread for that purpose rather than using the  
thread pool.

> Is ManualResetEvent.WaitOne() really blocking a Thread or is there any  
> job
> in the ThreadPool to let those waiting Threads not block all others in  
> the
> queue ?

The former.  The code you posted is, at least at its most basic, a good  
example of how one can deadlock the thread pool.  If all those thread pool  
threads are all blocked waiting on something to happen, and that something  
isn't going to happen until a newly assigned thread pool task executes,  
then since that new task will never execute, you'll never get anywhere.

You can correct this by changing the design so that either you have some  
way to unblock the threads without running a new thread pool task, or you  
simply move the blocking threads out of the thread pool altogether.

A third alternative would be to make sure you never consume the thread  
pool completely with threads that could block in that way.  That third  
solution isn't quite as reliable, since you could have other consumers of  
the thread pool doing the same sort of thing, resulting in all the  
consumers still managing to consume the thread pool entirely, without any  
threads that would unblock the threads being allowed to run.  So yet  
another alternative would be to implement your own thread pool, one that  
you know is used only for this purpose so that you can reliably limit the  
number of potentially blocking threads, ensuring you've always got at  
least one thread available that can unblock the blocking threads.

Of course, if all of your threads can theoretically be both blocking and  
unblocking threads, and if you have no way to determine which they are  
prior to executing them, this third solution isn't a solution at all.  :)

Yet another way to fix it would be to change the design dramatically,  
providing a way for threads that would otherwise have blocked to simply  
exit altogether, saving some sort of state so that you can resume  
executing whatever they were doing at some later point in time when the  
blocking condition is resolved.  That'd be a lot more complicated though.  
:)

Pete


    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Jeroen Mostert  
View profile  
 More options Feb 11 2008, 2:34 pm
Newsgroups: microsoft.public.dotnet.framework
From: Jeroen Mostert <jmost...@xs4all.nl>
Date: Mon, 11 Feb 2008 20:34:25 +0100
Local: Mon, Feb 11 2008 2:34 pm
Subject: Re: Delegate BeginInvoke and ManualResetEvent.WaitOne()

Use ThreadPool.RegisterWaitForSingleObject() instead. This way you don't
consume any worker threads until the object is actually signaled, and if the
thread pool is full, it will simply postpone handling until threads become
available.

Even this is not particularly efficient if you're handling a lot of events
this way, because some wait threads must still be occupied with the waiting
(one wait thread can wait on multiple objects, but this doesn't scale
forever). Try to leverage asynchronous programming patterns more. Instead of
waiting on an event, use or write a function that will call a callback when
the work is done.

If you must use synchronous processing (because the code isn't yours and you
can rewrite anything, for example) try to put a limit to the number of
simultaneous outstanding calls yourself. Do not rely on the thread pool to
stall when it runs out of wait threads, because you're in big trouble by
that point.

--
J.


    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Jon Skeet [ C# MVP ]  
View profile  
 More options Feb 11 2008, 2:43 pm
Newsgroups: microsoft.public.dotnet.framework
From: Jon Skeet [C# MVP] <sk...@pobox.com>
Date: Mon, 11 Feb 2008 19:43:37 -0000
Local: Mon, Feb 11 2008 2:43 pm
Subject: Re: Delegate BeginInvoke and ManualResetEvent.WaitOne()

Peter Duniho <NpOeStPe...@nnowslpianmk.com> wrote:

<snip lots>

> The thread pool is significantly larger than 25 threads in .NET 2.0 and  
> later.

<snip lots>

To be precise on this, it's 25 threads per processor on .NET 2.0, and
250 threads per processor on .NET 2.0 SP1.

See

http://www.bluebytesoftware.com/blog/PermaLink,guid,ca22a5a8-a3c9-4ee8-
9b41-667dbd7d2108.aspx

for more about this.

--
Jon Skeet - <sk...@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk


    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Peter Duniho  
View profile  
 More options Feb 12 2008, 1:23 pm
Newsgroups: microsoft.public.dotnet.framework
From: "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>
Date: Tue, 12 Feb 2008 10:23:30 -0800
Local: Tues, Feb 12 2008 1:23 pm
Subject: Re: Delegate BeginInvoke and ManualResetEvent.WaitOne()
On Tue, 12 Feb 2008 09:25:02 -0800, Alphapage  

<Alphap...@discussions.microsoft.com> wrote:
> Thanks everyone for those great explainations.
> You perfectly answer my questions.

> Another little interrogation comes in my mind:
> Does the machine free a thread in background if you use WaitOne() or
> Sleep(1000000) ? (It doesn't seem to do.)

Well, I already wrote that using WaitOne() does not free the thread.  So  
you should already know the answer to that part of your question.  As it  
happens, there are _no_ blocking methods that would "free a thread in  
background" by calling it.  The only thing that will return a thread to  
the thread pool is to exit from the delegate used to start executing that  
thread.

So, no...the thread isn't freed if you call Sleep() either.

> I can't find any doc and I'm afraid if a thread really sleeps during  
> 1000000
> and is not free by the system.

You should be afraid.  Don't sleep for any amount of time, and especially  
not 1000 seconds, and especially not in a thread pool thread.

Once in a rare while you might come across a situation in which calling  
Sleep() from a non-thread-pool thread is required.  If you find yourself  
thinking you need to do that in a thread pool thread, you've designed  
yourself into a corner and need to fix your design instead of exposing  
yourself to potential deadlocks.

> It seems to me to be a really bad management
> of the ThreadPool threads, doesn't it ?

Yes, it would be bad management on your part of your use of thread pool  
threads.

> If I run more waiting threads than the pool threads limit, my app is  
> dead.

That's right.  Don't do that.

Pete


    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Alphapage  
View profile  
 More options Feb 15 2008, 11:52 am
Newsgroups: microsoft.public.dotnet.framework
From: Alphapage <Alphap...@discussions.microsoft.com>
Date: Fri, 15 Feb 2008 08:52:00 -0800
Subject: RE: Delegate BeginInvoke and ManualResetEvent.WaitOne()
Thank you very much.
You show me what I mustn't do and give me the right way.
Perfect.

    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »

Create a group - Google Groups - Google Home - Terms of Service - Privacy Policy
©2010 Google