public void ThreadPoolTest()
 {
     ConcurrentQueue<int> underlying = new ConcurrentQueue<int>();
     bool? isFired = null;
     int? taken = null;
     using ( var target = new NotifiableBlockingCollection<int>( underlying, 1 ) )
     using ( var done = new ManualResetEventSlim() )
     {
         var registeredWaitHandle =
             ThreadPool.RegisterWaitForSingleObject(
                 target.ConsumerWaitHandle,
                 ( arg0, arg1 ) =>
                 {
                     int val;
                     ( arg0 as NotifiableBlockingCollection<int> ).Take( CancellationToken.None, out val );
                     isFired = arg1;
                     taken = val;
                     done.Set();
                 },
                 target,
                 -1,
                 true
             );
         try
         {
             Assert.False( done.Wait( TimeSpan.FromSeconds( 1 ) ) );
             int value = Environment.TickCount;
             bool isAdded;
             target.Add( value, CancellationToken.None, out isAdded );
             Assert.True( isAdded );
             Assert.True( done.Wait( TimeSpan.FromSeconds( 1 ) ) );
             Assert.False( isFired.Value );
             Assert.AreEqual( value, taken.Value );
         }
         finally
         {
             registeredWaitHandle.Unregister( target.ConsumerWaitHandle );
         }
     }
 }
        public void CancellationTest()
        {
            ConcurrentQueue<int> underlying = new ConcurrentQueue<int>();
            using ( var tokenSource = new CancellationTokenSource() )
            using ( var target = new NotifiableBlockingCollection<int>( underlying, 1 ) )
            using ( var ready = new ManualResetEventSlim() )
            {
                var thread =
                    new Thread(
                        item =>
                        {
                            ready.Set();
                            try
                            {
                                int dummy;
                                target.Take( tokenSource.Token, out dummy );
                                Assert.Fail( "Not blocked" );
                            }
                            catch ( OperationCanceledException ) { }
                            catch ( ThreadInterruptedException )
                            {
                                Assert.Fail( "Interuptted" );
                            }
                        }
                    );

                thread.Start( target );
                try
                {
                    Assert.True( ready.Wait( TimeSpan.FromSeconds( 1 ) ) );
                    Thread.Yield();
                    tokenSource.Cancel( true );
                    Assert.True( thread.Join( TimeSpan.FromSeconds( 1 ) ) );
                }
                finally
                {
                    if ( thread.IsAlive )
                    {
                        thread.Abort();
                    }
                }

                ready.Reset();
                bool added;
                target.Add( Environment.TickCount, CancellationToken.None, out added );
                Assert.True( added );
                thread =
                    new Thread(
                        item =>
                        {
                            ready.Set();
                            bool dummy;
                            try
                            {
                                ( item as NotifiableBlockingCollection<int> ).Add( Environment.TickCount, tokenSource.Token, out dummy );
                                Assert.Fail( "Not blocked." );
                            }
                            catch ( OperationCanceledException ) { }
                            catch ( ThreadInterruptedException )
                            {
                                Assert.Fail( "Interuppted." );
                            }
                        }
                    );

                thread.Start( target );
                try
                {
                    Assert.True( ready.Wait( TimeSpan.FromSeconds( 1 ) ) );
                    Thread.Yield();
                    tokenSource.Cancel( true );
                    Assert.True( thread.Join( TimeSpan.FromSeconds( 1 ) ) );
                }
                finally
                {
                    if ( thread.IsAlive )
                    {
                        thread.Abort();
                    }
                }
            }
        }
        public void EmptyTest()
        {
            ConcurrentQueue<int> underlying = new ConcurrentQueue<int>();
            using ( var target = new NotifiableBlockingCollection<int>( underlying, 1 ) )
            using ( var ready = new ManualResetEventSlim() )
            {
                var thread =
                    new Thread(
                        item =>
                        {
                            int dummy;
                            try
                            {
                                ready.Set();
                                ( item as NotifiableBlockingCollection<int> ).Take( CancellationToken.None, out dummy );
                                Assert.Fail( "Failed to block." );
                            }
                            catch ( ThreadInterruptedException ) { }
                        }
                    );

                thread.Start( target );
                try
                {
                    Assert.True( ready.Wait( TimeSpan.FromSeconds( 1 ) ) );
                    thread.Interrupt();
                    Assert.True( thread.Join( TimeSpan.FromSeconds( 1 ) ) );
                }
                finally
                {
                    if ( thread.IsAlive )
                    {
                        thread.Abort();
                    }
                }

                ready.Reset();
                bool? isOk = null;
                int expected = Environment.TickCount;
                thread =
                    new Thread(
                        item =>
                        {
                            int value;
                            ready.Set();
                            ( item as NotifiableBlockingCollection<int> ).Take( CancellationToken.None, out value );
                            isOk = ( expected == value );
                        }
                    );

                thread.Start( target );
                try
                {
                    Assert.True( ready.Wait( TimeSpan.FromSeconds( 1 ) ) );
                    Thread.Yield();
                    bool added;
                    target.Add( expected, CancellationToken.None, out added );
                    Assert.True( added );
                    Assert.True( thread.Join( TimeSpan.FromSeconds( 1 ) ) );
                    Assert.True( isOk.Value );
                }
                finally
                {
                    if ( thread.IsAlive )
                    {
                        thread.Abort();
                    }
                }
            }
        }