An ISV Buddy emailed me about a problem he was experiencing with ManualResetEvents and WaitHandle.WaitAll. He was creating and populating an array of ManualResetEvents, where each ManualResetEvent was being passed to a different thread that called Set and Reset on the event repeatedly. The original thread would call ManualResetEvent.WaitAll() on the array of ManualResetEvents. After performing millions of runs, he twice came across an instance where WaitMultiple (which is called from WaitAll) would throw an ApplicationException:

System.ApplicationException: The parameter is incorrect.

   at System.Threading.WaitHandle.WaitMultiple(WaitHandle[] waitHandles, Int32 millisecondsTimeout, Boolean exitContext, Boolean WaitAll)

   at System.Threading.WaitHandle.WaitAll(WaitHandle[] waitHandles, Int32 millisecondsTimeout, Boolean exitContext)

   at System.Threading.WaitHandle.WaitAll(WaitHandle[] waitHandles)

This seemed odd since MSDN explicitly states that an ApplicationException is thrown by a user program, not by the CLR. So, after I confirmed that the Everett documentation for WaitAll didn't mention ApplicationException as a thrown exception, I also reviewed the Whidbey documentation. The Whidbey docs listed ApplicationException as being thrown by WaitAll when the array of WaitHandles has no elements. In turns out that this is missing from the Everett documentation. At this point, I created a sample app to confirm the exception behavior in Everett. Once that succeeded, I tried it in Whidbey and discovered a different exception was thrown. This time, an ArgumentNullException was thrown when waitHandles had no elements. It turns out that the ApplicationException has been replaced in Whidbey, but the documentation hasn't been updated. So, a documentation bug helped me determine why an ApplicationException was incorrectly being thrown. Note that the documentation will be updated to reflect the new behavior.