make use of .net's BlockingCollection

This converts from a SpinWait to a Semaphore if there are no events after the SpinWait times out.  This prevents unneccesary spinning of the CPU when there are no events in the queue for long period of time.