public void RevolvingBuffers_Multithreaded()
        {
            // Arrange
            char[]        data       = "Hello, world!".ToArray();
            int           iterations = 10000;
            StringBuilder result     = new StringBuilder();

            string expected = String.Concat(Enumerable.Repeat("Hello, world!", iterations));

            RevolvingBuffers <char> buffers = new RevolvingBuffers <char>(2);

            Exception writingThreadException = null;
            Thread    writingThread          = new Thread(delegate()
            {
                try
                {
                    for (int i = 0; i < iterations; i++)
                    {
                        for (int i2 = 0; i2 < data.Length; i2++)
                        {
                            buffers.CopyDataToBuffer(data, i2, 1);
                        }
                    }
                }
                catch (Exception ex)
                {
                    writingThreadException = ex;
                }
            });

            Exception readingThreadException = null;
            Thread    readingThread          = new Thread(delegate()
            {
                try
                {
                    while (result.Length < data.Length * iterations)
                    {
                        result.Append(GetString(buffers.GetBufferedData()));
                    }
                }
                catch (Exception ex)
                {
                    readingThreadException = ex;
                }
            });

            // Act
            writingThread.Start();
            readingThread.Start();

            // Assert
            bool completed = readingThread.Join(millisecondsTimeout: 1000);

            AssertWithMessage.Null(writingThreadException, "Exception in writingThread: {0}", writingThreadException);
            AssertWithMessage.Null(readingThreadException, "Exception in readingThread: {0}", readingThreadException);
            Assert.True(completed, "Process did not complete.");

            AssertWithMessage.Equal(expected.Length, result.Length, "result.Length");
            Assert.Equal(expected, result.ToString());
        }
        internal Task HandlerMethod(byte[] buffer, int index, int count)
        {
            AssertWithMessage.Null(_handlerTcs, "More than one call to HandlerMethod is happening at the same time");

            TaskCompletionSource <object> handlerTcs = new TaskCompletionSource <object>();

            try
            {
                _response.Append(_encoding.GetString(buffer, index, count));

                if (Block)
                {
                    _handlerTcs = handlerTcs;
                }
                else
                {
                    handlerTcs.SetResult(null);
                }
            }
            catch (Exception ex)
            {
                handlerTcs.SetException(ex);
            }

            return(handlerTcs.Task);
        }
        void IHttpSocketAdapter.SetResponseHandler(ResponseHandler handler)
        {
            AssertWithMessage.Null(_responseHandler, "SetResponseHandler was called more than once.");
            AssertWithMessage.NotNull(handler, "SetResponseHandler was called with a null handler.");

            _responseHandler = handler;
        }
        Task <int> ISocketAdapter.ReceiveAsync(byte[] buffer, int offset, int count)
        {
            Assert.False(_disposed, "ReceiveAsync was called on a socket that has been disposed.");

            AssertWithMessage.Null(_receiveTcs, "Multiple calls to ReceiveAsync are occuring at the same time");

            _receiveTcs     = new TaskCompletionSource <int>();
            _receiverBuffer = new ArraySegment <byte>(buffer, offset, count);

            Task <int> resultTask = _receiveTcs.Task;

            PushBytesToReceiver();

            return(resultTask);
        }