title: Threading Exception: The number of WaitHandles must be less than or equal to 64
body: <p>The title is to make this easy to find for others having this error. I'm new to Threading, so this is really giving me heck. I'm getting this runtime error that crashed Cassini. This is code that I'm maintaining originally developed as a website project in VS 2003 and converted to a VS 2008 website project.</p>
  
  <p>Important Info:</p>
  
  <ul>
  <li>The number of objects in the <code>manualEvents</code> array is 128 in this case.</li>
  <li><code>products</code> is an array of Strings</li>
  <li>Need to support .NET 2.0</li>
  </ul>
  
  <pre class="lang-vb prettyprint-override"><code>For Each product As String In products
      If Not product.Trim().ToUpper().EndsWith("OBSOLETE") Then
          calls += 1
      End If
  Next
  Dim results(calls - 1) As DownloadResults
  'Dim manualEvents(calls - 1) As Threading.ManualResetEvent '128 objects in this case.
  Dim manualEvents(0) As Threading.ManualResetEvent
  manualEvents(0) = New Threading.ManualResetEvent(False)
  'NOTE: I don't think this will work because what is not seen here, is that
  '    this code is being used to populate and cache a long list of products,
  '    each with their own category, etc. Am I misunderstanding something?
  
  'initialize results structures
  'spawn background workers
  calls = 0
  For Each product As String In products
      If Not product.Trim().ToUpper().EndsWith("OBSOLETE") Then
          Dim result As New DownloadResults
  
          'manualEvents(calls) = New Threading.ManualResetEvent(False)
          'Moved above For Each after declaration of variable
  
          result.params.product = product
          result.params.category = docType
          'result.ManualEvent = manualEvents(calls)
          result.ManualEvent = manualEvents(0)
          result.Context = Me._context
  
          results(calls) = result
  
          Threading.ThreadPool.QueueUserWorkItem(AddressOf ProcessSingleCategoryProduct, results(calls))
          Threading.Interlocked.Increment(calls) 'Replaces below incrementation
  
          'calls += 1
      End If
  Next
  
  Threading.WaitHandle.WaitAll(manualEvents) 'CRASHES HERE
  </code></pre>
  
  <p>Thread Helper Function (for the sake of completion)</p>
  
  <pre class="lang-vb prettyprint-override"><code>Public Shared Sub ProcessSingleCategoryProduct(ByVal state As Object)
      Dim drs As DownloadResults = CType(state, DownloadResults)
      Dim adc As New cADCWebService(drs.Context)
  
      drs.docs = adc.DownloadADC(drs.params.category, drs.params.product)
      drs.ManualEvent.Set()
  End Sub
  </code></pre>