WaitHandle.WaitAll throws NotSupportedException when joining more than 64 WaitHandled

I was just looking after a Problem where a customer was not able to join more than 64 wait handles in a WaitOne method call.

This is because of an internal limitation trying to prevent you from exhaustive usage of synchronization primitives.

MSDN mentions it in the remark section:

https://msdn.microsoft.com/en-us/library/z6w25xa6(v=vs.90).aspx

“On some implementations, if more than 64 handles are passed, a NotSupportedException is thrown.”

My customer was under heavy time pressure with his project and just did not have enough time to refactor his threading approach which would have been the better solution actually.

So I suggested him to group all his waithandles in max 64 element arrays and joining them sequencially group by group.

The solution worked well thus I’m going to share it for you just in case … Smile

    1:   
    2:  using System;
    3:  using System.Collections.Generic;
    4:  using System.Diagnostics;
    5:  using System.Linq;
    6:  using System.Text;
    7:  using System.Threading;
    8:   
    9:  namespace Hook
   10:  {
   11:      class Program
   12:      {
   13:          static void Main(string[] args)
   14:          {
   15:              Thread[] threads = new Thread[128];
   16:              WaitHandle[] whs = new WaitHandle[64];
   17:              WaitHandle[] whs2 = new WaitHandle[64];
   18:              for (int i = 0; i < 128; i++)
   19:              {
   20:                  WaitHandle wh = new AutoResetEvent(false);
   21:                  if (i >= 64)
   22:                      whs2[i - 64] = wh;
   23:                  else
   24:                      whs[i] = wh;
   25:   
   26:                  threads[i] = new Thread(DoNo);
   27:                  threads[i].Start(wh);
   28:              }
   29:   
   30:              WaitHandle.WaitAll(whs);
   31:              WaitHandle.WaitAll(whs2);
   32:          }
   33:   
   34:          private static void DoNo(object obj)
   35:          {
   36:              Thread.Sleep(1000);
   37:              AutoResetEvent wh = (AutoResetEvent)obj;
   38:              wh.Set();
   39:          }
   40:      }
   41:  }

Hope it works for you, too!

Sebastian