private void OnConnected(Socket connectSocket, SocketAsyncEventArgs context, TaskCompletionSource <ClientTransport> taskCompletionSource)
        {
            try
            {
                if (connectSocket == null || !connectSocket.Connected)
                {
                    // canceled.
                    taskCompletionSource.SetException(
                        new RpcTransportException(
                            RpcError.ConnectionTimeoutError,
                            "Connect timeout.",
                            String.Format(CultureInfo.CurrentCulture, "Timeout: {0}", this.Configuration.ConnectTimeout)
                            )
                        );
                    return;
                }

#if !API_SIGNATURE_TEST
                MsgPackRpcClientProtocolsTrace.TraceEvent(
                    MsgPackRpcClientProtocolsTrace.EndConnect,
                    "Connected. {{ \"Socket\" : 0x{0:X}, \"RemoteEndPoint\" : \"{1}\", \"LocalEndPoint\" : \"{2}\" }}",
                    ClientTransport.GetHandle(connectSocket),
                    ClientTransport.GetRemoteEndPoint(connectSocket, context),
                    ClientTransport.GetLocalEndPoint(connectSocket)
                    );
#endif

                taskCompletionSource.SetResult(this.GetTransport(connectSocket));
            }
            finally
            {
                context.Dispose();
            }
        }
        private void OnCompleted(object sender, SocketAsyncEventArgs e)
        {
            var socket = sender as Socket;

#if MONO
            var userToken = e.UserToken as Tuple <TaskCompletionSource <ClientTransport>, ConnectTimeoutWatcher, Socket>;
#else
            var userToken = e.UserToken as Tuple <TaskCompletionSource <ClientTransport>, ConnectTimeoutWatcher>;
#endif
            var taskCompletionSource = userToken.Item1;
            var watcher = userToken.Item2;
            if (watcher != null)
            {
                this.EndConnectTimeoutWatch(watcher);
            }

#if MONO
            var error = this.HandleSocketError(userToken.Item3 ?? socket, e);
#else
            var error = this.HandleSocketError(e.ConnectSocket ?? socket, e);
#endif
            if (error != null)
            {
                taskCompletionSource.SetException(error.Value.ToException());
                return;
            }

            switch (e.LastOperation)
            {
            case SocketAsyncOperation.Connect:
            {
#if MONO
                this.OnConnected(userToken.Item3, e, taskCompletionSource);
#else
                this.OnConnected(e.ConnectSocket, e, taskCompletionSource);
#endif
                break;
            }

            default:
            {
#if !API_SIGNATURE_TEST
                MsgPackRpcClientProtocolsTrace.TraceEvent(
                    MsgPackRpcClientProtocolsTrace.UnexpectedLastOperation,
                    "Unexpected operation. {{ \"Socket\" : 0x{0:X}, \"RemoteEndPoint\" : \"{1}\", \"LocalEndPoint\" : \"{2}\", \"LastOperation\" : \"{3}\" }}",
                    ClientTransport.GetHandle(socket),
                    ClientTransport.GetRemoteEndPoint(socket, e),
                    ClientTransport.GetLocalEndPoint(socket),
                    e.LastOperation
                    );
#endif
                taskCompletionSource.SetException(new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, "Unknown socket operation : {0}", e.LastOperation)));
                break;
            }
            }
        }
        protected internal RpcErrorMessage?HandleSocketError(Socket socket, SocketAsyncEventArgs context)
        {
            if (context.SocketError.IsError() == false)
            {
                return(null);
            }

            MsgPackRpcClientProtocolsTrace.TraceEvent(
                MsgPackRpcClientProtocolsTrace.SocketError,
                "Socket error. {{ \"Socket\" : 0x{0:X}, \"RemoteEndpoint\" : \"{1}\", \"LocalEndpoint\" : \"{2}\", \"LastOperation\" : \"{3}\", \"SocketError\" : \"{4}\", \"ErrorCode\" : 0x{5:X} }}",
                ClientTransport.GetHandle(socket),
                ClientTransport.GetRemoteEndPoint(socket, context),
                ClientTransport.GetLocalEndPoint(socket),
                context.LastOperation,
                context.SocketError,
                ( int )context.SocketError
                );

            return(context.SocketError.ToClientRpcError());
        }