/// <summary>
        /// Remove link on remote proxy through rpc
        /// </summary>
        /// <param name="ct"></param>
        /// <returns></returns>
        private async Task UnlinkAsync(CancellationToken ct)
        {
            var request = Message.Create(_socket.Id, RemoteId, CloseRequest.Create());

            try {
                var response = await _socket.Provider.ControlChannel.CallAsync(Proxy,
                                                                               request, TimeSpan.FromSeconds(10), ct).ConfigureAwait(false);

                ProxyEventSource.Log.LinkRemoved(this);
                if (response != null)
                {
                    var errorCode = (SocketError)response.Error;
                    if (errorCode != SocketError.Success &&
                        errorCode != SocketError.Timeout &&
                        errorCode != SocketError.Closed)
                    {
                        throw new SocketException(errorCode);
                    }
                }
            }
            catch (Exception e) when(!(e is SocketException))
            {
                throw SocketException.Create("Failed to close", e);
            }
            finally {
                request.Dispose();
            }
        }
        /// <summary>
        /// Close the stream part
        /// </summary>
        /// <param name="ct"></param>
        /// <returns></returns>
        private async Task TerminateConnectionAsync(CancellationToken ct)
        {
            var connection = _connection;

            _connection = null;

            ProxyEventSource.Log.StreamClosing(this, null);
            try {
                try {
                    await SendBlock.SendAsync(Message.Create(_socket.Id, RemoteId,
                                                             CloseRequest.Create()), ct).ConfigureAwait(false);
                }
                catch { }
                try {
                    await connection.CloseAsync().ConfigureAwait(false);
                }
                catch { }

                // try {
                //     SendBlock.Complete();
                //     await SendBlock.Completion.ConfigureAwait(false);
                // }
                // catch { }
                // try {
                //     ReceiveBlock.Complete();
                //     await ReceiveBlock.Completion.ConfigureAwait(false);
                // }
                // catch { }
            }
            finally {
                ProxyEventSource.Log.StreamClosed(this, null);
            }
        }