public void TestClearBuffer_BuffersAreClear()
        {
            int    messageId  = Environment.TickCount;
            string methodName = Guid.NewGuid().ToString();
            Action <ClientResponseContext, Exception, Boolean> completionCallback = (_0, _1, _2) => { };

            var target = new ClientRequestContext();

            target.RenewSessionId();
            target.SetRequest(messageId, methodName, completionCallback);
            target.ArgumentsPacker.Pack(1);
            target.ClearBuffers();

            Assert.That(target.ArgumentsPacker, Is.Not.Null);
            Assert.That(target.ArgumentsPacker.Position, Is.EqualTo(0));
            Assert.That(target.BoundTransport, Is.Null);
            Assert.That(target.MessageId, Is.Not.Null);
            Assert.That(target.MessageType, Is.EqualTo(MessageType.Request));
            Assert.That(target.MethodName, Is.Not.Null);
            Assert.That(target.NotificationCompletionCallback, Is.Null);
            Assert.That(target.RequestCompletionCallback, Is.Not.Null);
            Assert.That(target.SendingBuffer.All(segment => segment.Array == null));
            Assert.That(target.SessionId, Is.Not.EqualTo(0));
            Assert.That(target.SessionStartedAt, Is.Not.EqualTo(default(DateTimeOffset)));
        }
		public void TestClearBuffer_BuffersAreClear()
		{
			int messageId = Environment.TickCount;
			string methodName = Guid.NewGuid().ToString();
			Action<ClientResponseContext, Exception, Boolean> completionCallback = ( _0, _1, _2 ) => { };

			var target = new ClientRequestContext();
			target.RenewSessionId();
			target.SetRequest( messageId, methodName, completionCallback );
			target.ArgumentsPacker.Pack( 1 );
			target.ClearBuffers();

			Assert.That( target.ArgumentsPacker, Is.Not.Null );
			Assert.That( target.ArgumentsPacker.Position, Is.EqualTo( 0 ) );
			Assert.That( target.BoundTransport, Is.Null );
			Assert.That( target.MessageId, Is.Not.Null );
			Assert.That( target.MessageType, Is.EqualTo( MessageType.Request ) );
			Assert.That( target.MethodName, Is.Not.Null );
			Assert.That( target.NotificationCompletionCallback, Is.Null );
			Assert.That( target.RequestCompletionCallback, Is.Not.Null );
			Assert.That( target.SendingBuffer.All( segment => segment.Array == null ) );
			Assert.That( target.SessionId, Is.Not.EqualTo( 0 ) );
			Assert.That( target.SessionStartedAt, Is.Not.EqualTo( default( DateTimeOffset ) ) );
		}
        /// <summary>
        ///		Called when asynchronous 'Send' operation is completed.
        /// </summary>
        /// <param name="context">Context information.</param>
        /// <returns>
        ///		<c>true</c>, if the subsequent request is already received;
        ///		<c>false</c>, otherwise.
        /// </returns>
        ///	<exception cref="InvalidOperationException">
        ///		This instance is not in 'Sending' state.
        ///	</exception>
        ///	<exception cref="ObjectDisposedException">
        ///		This instance is disposed.
        ///	</exception>
        protected virtual void OnSent(ClientRequestContext context)
        {
            if (MsgPackRpcClientProtocolsTrace.ShouldTrace(MsgPackRpcClientProtocolsTrace.SentOutboundData))
            {
                var socket = this.BoundSocket;
                MsgPackRpcClientProtocolsTrace.TraceEvent(
                    MsgPackRpcClientProtocolsTrace.SentOutboundData,
                    "Sent request/notification. {{ \"SessionID\" : {0}, \"Socket\" : 0x{1:X}, \"RemoteEndPoint\" : \"{2}\", \"LocalEndPoint\" : \"{3}\", \"Type\" : \"{4}\", \"MessageID\" : {5}, \"Method\" : \"{6}\", \"BytesTransferred\" : {7} }}",
                    context.SessionId,
                    GetHandle(socket),
                    GetRemoteEndPoint(socket, context),
                    GetLocalEndPoint(socket),
                    context.MessageType,
                    context.MessageId,
                    context.MethodName,
                    context.BytesTransferred
                    );
            }

            context.StopWatchTimeout();
            context.Timeout -= this.OnSendTimeout;

            context.ClearBuffers();

            if (context.MessageType == MessageType.Notification)
            {
                try
                {
                    Action <Exception, bool> handler = null;
                    try
                    {
                        this._pendingNotificationTable.TryRemove(context.SessionId, out handler);
                    }
                    finally
                    {
                        var rpcError = context.SocketError.ToClientRpcError();
                        if (handler != null)
                        {
                            handler(rpcError.IsSuccess ? null : rpcError.ToException(), context.CompletedSynchronously);
                        }
                    }
                }
                finally
                {
                    this.Manager.ReturnRequestContext(context);
                    this.OnProcessFinished();
                    this.Manager.ReturnTransport(this);
                }
            }
            else
            {
                if (this.Manager.Configuration.WaitTimeout != null &&
                    (this.Manager.Configuration.WaitTimeout.Value - context.ElapsedTime).TotalMilliseconds < 1.0)
                {
                    this.OnWaitTimeout(context);
                    this.Manager.ReturnRequestContext(context);
                    this.Manager.ReturnTransport(this);
                    return;
                }

                var responseContext = this.Manager.GetResponseContext(this, context.RemoteEndPoint);

                if (this.Manager.Configuration.WaitTimeout != null)
                {
                    responseContext.Timeout += this.OnReceiveTimeout;
                    responseContext.StartWatchTimeout(this.Manager.Configuration.WaitTimeout.Value - context.ElapsedTime);
                }

                this.Manager.ReturnRequestContext(context);
                this.Receive(responseContext);
            }
        }