Ejemplo n.º 1
0
        public async Task ConnectAsync()
        {
            ThrowIfDisposed();

            await _sync.WaitAsync().ConfigureAwait(false);

            try
            {
                if (IsConnected)
                {
                    return;
                }

                DoSafeRelease();

                _cancellation = new CancellationTokenSource();

                IList <IOp> opsReceivedWhileConnecting;

                (_connection, opsReceivedWhileConnecting) =
                    await _connectionManager.OpenConnectionAsync(_connectionInfo, _cancellation.Token).ConfigureAwait(false);

                _consumer = _consumerFactory
                            .Run(ConsumerWork, _cancellation.Token)
                            .ContinueWith(async t =>
                {
                    if (_isDisposed)
                    {
                        return;
                    }

                    await _sync.WaitAsync().ConfigureAwait(false);

                    try
                    {
                        if (_isDisposed)
                        {
                            return;
                        }

                        if (!t.IsFaulted)
                        {
                            return;
                        }

                        DoSafeRelease();

                        _eventMediator.Emit(new ClientDisconnected(this, DisconnectReason.DueToFailure));

                        var ex = t.Exception?.GetBaseException() ?? t.Exception;
                        if (ex == null)
                        {
                            return;
                        }

                        _logger.Error("Internal client worker exception.", ex);

                        _eventMediator.Emit(new ClientWorkerFailed(this, ex));
                    }
                    catch (Exception ex)
                    {
                        _logger.Error("Unhandled exception while ending worker.", ex);
                    }
                    finally
                    {
                        _sync?.Release();
                    }
                });

                _eventMediator.Emit(new ClientConnected(this));

                if (opsReceivedWhileConnecting.Any())
                {
                    _opMediator.Emit(opsReceivedWhileConnecting);
                }

                await DoSubAsync(_subscriptions.Values.Select(i => i.SubscriptionInfo).ToArray()).ConfigureAwait(false);
            }
            finally
            {
                _sync.Release();
            }
        }