public async Task <bool> TrySwitchBrokerAsync(string name, BrokerConnectionInfo connectionInfo = default(BrokerConnectionInfo), CancellationToken cancellationToken = default(CancellationToken)) { using (_disposeToken.Link(ref cancellationToken)) { await TaskUtilities.SwitchToBackgroundThread(); var brokerClient = CreateBrokerClient(name, connectionInfo, cancellationToken); if (brokerClient == null) { return(false); } // Broker switching shouldn't be concurrent IAsyncReaderWriterLockToken lockToken; try { lockToken = await _connectArwl.WriterLockAsync(cancellationToken); } catch (OperationCanceledException) { brokerClient.Dispose(); return(false); } if (brokerClient.ConnectionInfo.Equals(_brokerProxy.ConnectionInfo)) { brokerClient.Dispose(); try { // Switching to the broker that is currently running and connected is always successful if (IsConnected) { return(true); } await ReconnectAsync(cancellationToken); } catch (Exception) { return(false); } finally { lockToken.Dispose(); } IsConnected = true; return(true); } // First switch broker proxy so that all new sessions are created for the new broker var oldBroker = _brokerProxy.Set(brokerClient); if (_updateHostLoadLoopTask == null) { _updateHostLoadLoopTask = UpdateHostLoadLoopAsync(); } try { BrokerChanging?.Invoke(this, EventArgs.Empty); await SwitchBrokerAsync(cancellationToken); oldBroker.Dispose(); } catch (Exception ex) { _brokerProxy.Set(oldBroker); if (_disposeToken.IsDisposed) { oldBroker.Dispose(); } brokerClient.Dispose(); BrokerChangeFailed?.Invoke(this, EventArgs.Empty); if (ex is OperationCanceledException || ex is ComponentBinaryMissingException) { // RHostDisconnectedException is derived from OperationCanceledException return(false); } throw; } finally { lockToken.Dispose(); } IsConnected = true; OnBrokerChanged(); return(true); } }
public async Task <bool> TrySwitchBrokerAsync(string name, string path = null, CancellationToken cancellationToken = default(CancellationToken)) { await TaskUtilities.SwitchToBackgroundThread(); var brokerClient = CreateBrokerClient(name, path); if (brokerClient == null) { return(false); } // Broker switching shouldn't be concurrent IAsyncReaderWriterLockToken lockToken = null; try { lockToken = await _connectArwl.WriterLockAsync(cancellationToken); } catch (OperationCanceledException) { lockToken?.Dispose(); brokerClient.Dispose(); return(false); } if (brokerClient.Name.EqualsOrdinal(_brokerProxy.Name) && brokerClient.Uri.AbsoluteUri.PathEquals(_brokerProxy.Uri.AbsoluteUri)) { brokerClient.Dispose(); try { // Switching to the broker that is currently running and connected is always successful if (IsConnected) { return(true); } await ReconnectAsync(cancellationToken, lockToken.Reentrancy); } catch (Exception) { return(false); } finally { lockToken.Dispose(); } OnBrokerConnected(); return(true); } // First switch broker proxy so that all new sessions are created for the new broker var oldBroker = _brokerProxy.Set(brokerClient); try { BrokerChanging?.Invoke(this, EventArgs.Empty); await SwitchBrokerAsync(oldBroker, cancellationToken, lockToken.Reentrancy); oldBroker.Dispose(); if (brokerClient.IsRemote) { _callback.Write(Environment.NewLine + Resources.Connected + Environment.NewLine); PrintBrokerInformation(); } } catch (Exception ex) { _brokerProxy.Set(oldBroker); brokerClient.Dispose(); BrokerChangeFailed?.Invoke(this, EventArgs.Empty); if (ex is OperationCanceledException || ex is RHostBrokerBinaryMissingException) // RHostDisconnectedException is derived from OperationCanceledException { return(false); } throw; } finally { lockToken.Dispose(); } OnBrokerConnected(); BrokerChanged?.Invoke(this, new EventArgs()); return(true); }