Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / CLR / December 2006

Tip: Looking for answers? Try searching our database.

WaitHandles must be less than or equal to 64 - missing documentation

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Loy - 24 Dec 2006 10:12 GMT
Calling WaitAll with array of 64 or more causes exception
WaitHandle.WaitAll(whaWaitHandlesArray);

System.NotSupportedException: The number of WaitHandles must be less
than or equal to 64.
  at System.Threading.WaitHandle.WaitAll(WaitHandle[] waitHandles,
Int32 millisecondsTimeout, Boolean exitContext)
  at System.Threading.WaitHandle.WaitAll(WaitHandle[] waitHandles)

Searching for the error string revealed no KB article or MSDN
documentation.
I did found MSFT answer regarding that on:
http://groups.google.com/group/microsoft.public.sqlserver.notificationsvcs/tree/
browse_frm/thread/1e10fc93cf194775/1d8e7ee0e1a3f41c


The API documentation says it might throw NotSupportedException under
the condition: "The number of objects in waitHandles is greater than
the system permits."

My questions are:
1. How can I find the system limitation? what does it depends on?
2. Any kb article that will provide link from the exception message to
the real cause will be helpful for all the developers and will save us
google time

(About Google Vs www.Live.com - Live did not find even a single match
...)

Loy
Peter Ritchie [C# MVP] - 25 Dec 2006 01:10 GMT
In .NET 2.0 it's simply hard coded to 64.  This is based upon the limit of
object handles that the Win32 function WaitForMultipleObjectsEx can
support--which is documented as being MAXIMUM_WAIT_OBJECTS, or 64.

If you want to wait for more than 64 handles you'll have to break it into
chunks of 64 and create a thread for each <=64 chunk that sets another
WaitHandle that is waited upon in some "main" thread (can't be the main
thread in a WinForms application)--which would give you the ability to wait
on 64 blocks of 64 wait handles.  More than that and you'd have to break out
to 3 levels.  I think there's an example or two on the web of handling more
than 64 handles...

Signature

Browse http://connect.microsoft.com/VisualStudio/feedback/ and vote.
http://www.peterRitchie.com/blog/
Microsoft MVP, Visual Developer - Visual C#

> Calling WaitAll with array of 64 or more causes exception
> WaitHandle.WaitAll(whaWaitHandlesArray);
[quoted text clipped - 24 lines]
>
> Loy
William Stacey [C# MVP] - 25 Dec 2006 03:06 GMT
Fortunately, WaitAll is easy to implement with any number of handles.  Here
is a simple example.

       public static void WaitAll(WaitHandle[] handles)
       {
           if (handles == null)
               throw new ArgumentNullException("handles");
           foreach (WaitHandle wh in handles)
           {
               wh.WaitOne();
           }
       }

Signature

William Stacey [C# MVP]

| Calling WaitAll with array of 64 or more causes exception
| WaitHandle.WaitAll(whaWaitHandlesArray);
[quoted text clipped - 8 lines]
| documentation.
| I did found MSFT answer regarding that on:

http://groups.google.com/group/microsoft.public.sqlserver.notificationsvcs/tree/
browse_frm/thread/1e10fc93cf194775/1d8e7ee0e1a3f41c


| The API documentation says it might throw NotSupportedException under
| the condition: "The number of objects in waitHandles is greater than
[quoted text clipped - 10 lines]
|
| Loy
Ben Voigt - 26 Dec 2006 20:30 GMT
> Fortunately, WaitAll is easy to implement with any number of handles.
> Here
> is a simple example.

Which does not replicate the proper semantics and therefore is vulnerable to
deadlock.

>        public static void WaitAll(WaitHandle[] handles)
>        {
[quoted text clipped - 35 lines]
> |
> | Loy
William Stacey [C# MVP] - 27 Dec 2006 00:37 GMT
How so?

Signature

William Stacey [C# MVP]

| > Fortunately, WaitAll is easy to implement with any number of handles.
| > Here
| > is a simple example.
|
| Which does not replicate the proper semantics and therefore is vulnerable to
| deadlock.
Peter Ritchie [C# MVP] - 27 Dec 2006 02:30 GMT
My calling WaitOne in a loop like that you're allowing the thread to gain
ownership of a WaitHandle without having ownership of all WaitHandles.  
WaitAll does not give ownership of all WaitHandes until all WaitHandles have
entered a signaled state.

WaitAll can be given a timeout, if that timeout expires before all
WaitHandles are signaled the thread never gains ownership of any of the
WaitHandles even if some of them have signaled.

BTW, you'd have this same problem if had to split up more thane 64
WaitHandles across multiple threads with multiple calls to WaitAll...

Signature

Browse http://connect.microsoft.com/VisualStudio/feedback/ and vote.
http://www.peterRitchie.com/blog/
Microsoft MVP, Visual Developer - Visual C#

> How so?
>
[quoted text clipped - 5 lines]
> to
> | deadlock.
William Stacey [C# MVP] - 27 Dec 2006 05:26 GMT
This can get slightly more involved and depends on the handle type.  If the
wait events are ManualResetEvents, then a timeout may not matter to your
code as they stay signaled anyway.  AutoResetEvents are more an issue as
some may be reset by the WaitOne() call before the timeout and that could
get messy - but can still be workable depending on needs.  Semaphores,
however, do change their state even with the win32 waitformultipleobjects as
it waits for each one in turn (so the net effect would be the same as using
the shown implementation).  If one understands the potential issues and
takes care, the pattern can prove useful when waiting on many handles.

Signature

William Stacey [C# MVP]

| My calling WaitOne in a loop like that you're allowing the thread to gain
| ownership of a WaitHandle without having ownership of all WaitHandles.
[quoted text clipped - 17 lines]
| > to
| > | deadlock.
Loy - 27 Dec 2006 12:33 GMT
Thank you all for your reply

I implemented the simple workaround with the limitation that it works
only if the handles are not reset again during the wait time.

In my case this is a valid limitation as I wait for objects to close
and the handle is nullified in the objects once it is set.

Being aware of this issue - if there is a correct implementation - why
doesn't the dot net team implement it as part of the framework?

On the documentation side - Need to be clear on how to know your system
limitation
A kb article is the least that I would expect with regard to this
issue.

Am I wrong?

Thanks

Loy

> This can get slightly more involved and depends on the handle type.  If the
> wait events are ManualResetEvents, then a timeout may not matter to your
[quoted text clipped - 41 lines]
> | > to
> | > | deadlock.
Ben Voigt - 27 Dec 2006 23:04 GMT
> How so?

I think Peter has done a fantastic job of explaining why this is so.  If you
still aren't convinced there is a significant difference between:

WaitForMultipleObjects({A, B, C, D});
and
WaitForSingleObject(A);WaitForSingle(B);WaitForSingle(C);WaitForSingle(D);

then I will be happy to clarify.

> | > Fortunately, WaitAll is easy to implement with any number of handles.
> | > Here
[quoted text clipped - 4 lines]
> to
> | deadlock.
William Stacey [C# MVP] - 28 Dec 2006 21:43 GMT
| I think Peter has done a fantastic job of explaining why this is so.

Totally agree.

| still aren't convinced there is a significant difference between:
|
[quoted text clipped - 3 lines]
|
| then I will be happy to clarify.

Thanks Ben.  Not sure there is any confusion on that.  I think we/I
meandered into some different areas.  All is good.  Happy New Year.

Signature

William Stacey [C# MVP]

Ben Voigt - 26 Dec 2006 20:31 GMT
> Calling WaitAll with array of 64 or more causes exception
> WaitHandle.WaitAll(whaWaitHandlesArray);
[quoted text clipped - 4 lines]
> Int32 millisecondsTimeout, Boolean exitContext)
>   at System.Threading.WaitHandle.WaitAll(WaitHandle[] waitHandles)

At this point you should re-architect your application to use fewer wait
handles.  What kind of object are you waiting on and why do you need so
many?

> Searching for the error string revealed no KB article or MSDN
> documentation.
[quoted text clipped - 15 lines]
>
> Loy

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.