//private CancellationTokenSource _channelCancellSource;
        //private CancellationTokenSource _source;
        private async Task ListenAction(CancellationToken token)
        {
            TcpListener tcpListener = new TcpListener(IPAddress.Any, port);
            Action      cleanup     = () =>
            {
                tcpListener?.Stop();
                tcpListener = null;
            };

            token.Register(cleanup);

            try
            {
                tcpListener.Start();
            }
            catch (Exception)
            {
                throw new Exception("Can not start ChannelManager, Port is occupied.");
            }

            while (!token.IsCancellationRequested)
            {
                TcpClient client = await tcpListener.AcceptTcpClientAsync();

#pragma warning disable 4014
                Task.Run(() =>
#pragma warning restore 4014
                {
                    var channel          = new TcpChannel(client);
                    channel.IsInitiative = false;
                    //没有发送任何事件,直到收到Connect消息。
                    ChannelCreated?.Invoke(channel);
                }, token);
            }
            cleanup();
            //TODO 需要测试! 如果_listenTask.Wait, 这里把_listenTask设置为null,是不会报错。
            Stop();
        }
        private void ConnectSingleIpAsync(string ip, [NotNull] TaskCompletionSource <IChannel> tcs, ICollection <string> candidateIps)
        {
            Task.Run(async() =>
            {
                bool socketAdopted      = false;
                var client              = new TcpClient();
                Action disposeTcpClient = () =>
                {
                    // ReSharper disable once AccessToModifiedClosure
                    if (socketAdopted)
                    {
                        return;
                    }

                    client?.Dispose();
                    client = null;
                    Env.Logger.Log($"clean up [{ip}]", nameof(ChannelManager));
                };

                try
                {
                    Env.Logger.Log($"Try to connect to [{ip}]", nameof(ChannelManager));
                    await client.ConnectAsync(ip, port); //这个耗时的过程不能取消,cancel token就没多大意义了。
                    if (!tcs.IsEnded() && client.Connected)
                    {
                        IPEndPoint remote = client.Client.RemoteEndPoint as IPEndPoint;
                        if (remote != null)
                        {
                            socketAdopted      = true;
                            TcpChannel channel = new TcpChannel(client)
                            {
                                IsInitiative = true,
                                RemoteIP     = remote.Address.ToString()
                            };
                            socketAdopted = tcs.TrySetResult(channel);
                            if (socketAdopted)
                            {
                                Env.Logger.Log($"Connected to [{ip}] successfully", nameof(ChannelManager));
                            }
                        }
                    }
                    //如果这个不成功,不要设置result,让别的连接尝试做这个工作。
                }
                catch (Exception e)
                {
                    //如果全都失败应该早点退出。
                    Env.Logger.Log($"Create TCP Client failed {ip} reason {e.Message}", nameof(ChannelManager));
                }
                finally
                {
                    if (!socketAdopted)
                    {
                        candidateIps.Remove(ip);
                        if (candidateIps.Count == 0)
                        {
                            tcs.TrySetResult(null);
                        }

                        disposeTcpClient();
                    }
                }
            });
        }