public PollingClientEventLoop( Func<ClientSessionContext, RpcClient> sessionFactory, RpcClientOptions options, EventHandler<RpcTransportErrorEventArgs> errorHandler ) : base(sessionFactory, options, errorHandler) { this._cancellationTokenSource = new CancellationTokenSource(); int connectingConcurrency = options == null ? Environment.ProcessorCount / 5 + 1 : ( options.ConnectingConcurrency ?? Environment.ProcessorCount / 5 + 1 ); int sendingConcurrency = options == null ? ( Environment.ProcessorCount / 5 + 1 ) * 2 : ( options.SendingConcurrency ?? ( Environment.ProcessorCount / 5 + 1 ) * 2 ); int receivingConcurrency = options == null ? ( Environment.ProcessorCount / 5 + 1 ) * 2 : ( options.ReceivingConcurrency ?? ( Environment.ProcessorCount / 5 + 1 ) * 2 ); this._connectingQueue = new NotifiableBlockingCollection<ClientSocketAsyncEventArgs>( new ConcurrentQueue<ClientSocketAsyncEventArgs>(), options == null ? connectingConcurrency * 4 : ( options.ConnectingQueueLength ?? connectingConcurrency * 4 ) ); this._sendingQueue = new NotifiableBlockingCollection<ClientSocketAsyncEventArgs>( new ConcurrentQueue<ClientSocketAsyncEventArgs>(), options == null ? sendingConcurrency * 4 : ( options.SendingQueueLength ?? sendingConcurrency * 4 ) ); for ( int i = 0; i < connectingConcurrency; i++ ) { this.BeginWaitForOnConnecting(); } for ( int i = 0; i < sendingConcurrency; i++ ) { this.BeginWaitForOnSending(); } this._inBoundPollingThread = new Thread( this.PollInBound ); this._inBoundPollingThread.IsBackground = true; this._inBoundPollingThread.Name = String.Format( CultureInfo.InvariantCulture, "{0}({1}).InBoundPollingThread", this.GetType().Name, this.GetHashCode() ); this._inBoundPollingThread.Start( this._cancellationTokenSource.Token ); }
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 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 LimitationTest() { ConcurrentQueue<int> underlying = new ConcurrentQueue<int>(); Random random = new Random(); int expected1 = random.Next(); int expected2 = random.Next(); using ( var target = new NotifiableBlockingCollection<int>( underlying, 1 ) ) using ( var ready = new ManualResetEventSlim() ) { var thread = new Thread( item => { bool added; ( item as NotifiableBlockingCollection<int> ).Add( expected1, CancellationToken.None, out added ); Assert.True( added ); added = false; try { ready.Set(); ( item as NotifiableBlockingCollection<int> ).Add( expected2, CancellationToken.None, out added ); 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(); thread = new Thread( item => { ready.Set(); bool added; ( item as NotifiableBlockingCollection<int> ).Add( expected2, CancellationToken.None, out added ); Assert.True( added ); } ); thread.Start( target ); try { Assert.True( ready.Wait( TimeSpan.FromSeconds( 1 ) ) ); Thread.Yield(); int value; target.Take( CancellationToken.None, out value ); Assert.AreEqual( expected1, value ); Assert.True( thread.Join( TimeSpan.FromSeconds( 1 ) ) ); target.Take( CancellationToken.None, out value ); Assert.AreEqual( expected2, value ); } 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(); } } } }