public async Task <SharedConnectionContext> Attach(CancellationToken cancellationToken)
            {
                var context = new SharedConnectionContext(await _connectionContext.Task, cancellationToken);

                _attached.Add(context);
                return(context);
            }
        async Task SendUsingExistingConnection(IPipe <ConnectionContext> connectionPipe, CancellationToken cancellationToken, ConnectionScope scope)
        {
            try
            {
                using (SharedConnectionContext context = await scope.Attach(cancellationToken).ConfigureAwait(false))
                {
                    if (_log.IsDebugEnabled)
                    {
                        _log.DebugFormat("Using existing connection: {0}", ((ConnectionContext)context).HostSettings.ToDebugString());
                    }

                    await connectionPipe.Send(context).ConfigureAwait(false);
                }
            }
            catch (BrokerUnreachableException ex)
            {
                if (_log.IsDebugEnabled)
                {
                    _log.Debug("The connection usage threw an exception", ex);
                }

                throw new RabbitMqConnectionException("Connect failed: " + _connectionFactory.ToDebugString(), ex);
            }
            catch (Exception ex)
            {
                if (_log.IsDebugEnabled)
                {
                    _log.Debug("The existing connection usage threw an exception", ex);
                }

                throw;
            }
        }
        async Task <ConnectionContext> CreateSharedConnection(Task <ConnectionContext> context, CancellationToken cancellationToken)
        {
            var connectionContext = await context.ConfigureAwait(false);

            var sharedConnection = new SharedConnectionContext(connectionContext, cancellationToken);

            return(sharedConnection);
        }
        static async Task SendUsingExistingConnection(IPipe <ConnectionContext> connectionPipe, CancellationToken cancellationToken, ConnectionScope scope)
        {
            try
            {
                using (SharedConnectionContext context = await scope.Attach(cancellationToken))
                {
                    if (_log.IsDebugEnabled)
                    {
                        _log.DebugFormat("Using existing connection: {0}", ((ConnectionContext)context).HostSettings.ToDebugString());
                    }

                    await connectionPipe.Send(context);
                }
            }
            catch (Exception ex)
            {
                if (_log.IsDebugEnabled)
                {
                    _log.Debug("The existing connection usage threw an exception", ex);
                }

                throw;
            }
        }
        async Task SendUsingNewConnection(IPipe <ConnectionContext> connectionPipe, ConnectionScope scope, CancellationToken cancellationToken)
        {
            try
            {
                if (_signal.CancellationToken.IsCancellationRequested)
                {
                    throw new TaskCanceledException($"The connection is being disconnected: {_settings.ToDebugString()}");
                }

                if (_log.IsDebugEnabled)
                {
                    _log.DebugFormat("Connecting: {0}", _connectionFactory.ToDebugString());
                }

                IConnection connection = _connectionFactory.CreateConnection();

                if (_log.IsDebugEnabled)
                {
                    _log.DebugFormat("Connected: {0} (address: {1}, local: {2}", _connectionFactory.ToDebugString(),
                                     connection.RemoteEndPoint, connection.LocalEndPoint);
                }

                EventHandler <ShutdownEventArgs> connectionShutdown = null;
                connectionShutdown = (obj, reason) =>
                {
                    connection.ConnectionShutdown -= connectionShutdown;

                    Interlocked.CompareExchange(ref _scope, null, scope);

                    scope.Close();
                };

                connection.ConnectionShutdown += connectionShutdown;

                var connectionContext = new RabbitMqConnectionContext(connection, _settings, _signal.CancellationToken);

                connectionContext.GetOrAddPayload(() => _settings);

                scope.Connected(connectionContext);
            }
            catch (BrokerUnreachableException ex)
            {
                Interlocked.CompareExchange(ref _scope, null, scope);

                scope.ConnectFaulted(ex);

                throw new RabbitMqConnectionException("Connect failed: " + _connectionFactory.ToDebugString(), ex);
            }

            try
            {
                using (SharedConnectionContext context = await scope.Attach(cancellationToken))
                {
                    if (_log.IsDebugEnabled)
                    {
                        _log.DebugFormat("Using new connection: {0}", ((ConnectionContext)context).HostSettings.ToDebugString());
                    }

                    await connectionPipe.Send(context);
                }
            }
            catch (Exception ex)
            {
                if (_log.IsDebugEnabled)
                {
                    _log.Debug("The connection usage threw an exception", ex);
                }

                throw;
            }
        }
            public async Task<SharedConnectionContext> Attach(CancellationToken cancellationToken)
            {
                var context = new SharedConnectionContext(await _connectionContext.Task, cancellationToken);

                _attached.Add(context);
                return context;
            }