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(); } }