コード例 #1
0
        public static async Task <DBusConnection> ConnectAsync(ClientSetupResult connectionContext, Action <Exception> onDisconnect, CancellationToken cancellationToken, IEnumerable <IClientObjectProvider> clientProviders)
        {
            var _entries = AddressEntry.ParseEntries(connectionContext.ConnectionAddress);

            if (_entries.Length == 0)
            {
                throw new ArgumentException("No addresses were found", nameof(connectionContext.ConnectionAddress));
            }

            Guid           _serverId = Guid.Empty;
            IMessageStream stream    = null;
            var            index     = 0;

            while (index < _entries.Length)
            {
                AddressEntry entry = _entries[index++];

                _serverId = entry.Guid;
                try
                {
                    stream = await Transport.ConnectAsync(entry, connectionContext, cancellationToken)
                             .TimeoutAfter(connectionContext.InitialTimeout)
                             .ConfigureAwait(false);
                }
                catch
                {
                    if (index < _entries.Length)
                    {
                        continue;
                    }
                    throw;
                }

                break;
            }
            return(await CreateAndConnectAsync(stream, onDisconnect, clientProviders, true, connectionContext.InitialTimeout));
        }
コード例 #2
0
ファイル: Connection.cs プロジェクト: matdug/Tmds.DBus
        private async Task <DBusConnection> DoConnectAsync()
        {
            Task <DBusConnection> connectionTask = null;
            bool alreadyConnecting = false;

            lock (_gate)
            {
                if (_disposed)
                {
                    ThrowDisposed();
                }

                if (_connectionType == ConnectionType.ClientManual)
                {
                    if (_state != ConnectionState.Created)
                    {
                        throw new InvalidOperationException("Can only connect once");
                    }
                }
                else
                {
                    if (_state == ConnectionState.Connecting || _state == ConnectionState.Connected)
                    {
                        connectionTask    = _dbusConnectionTask;
                        alreadyConnecting = true;
                    }
                }
                if (!alreadyConnecting)
                {
                    _connectCts         = new CancellationTokenSource();
                    _dbusConnectionTcs  = new TaskCompletionSource <DBusConnection>();
                    _dbusConnectionTask = _dbusConnectionTcs.Task;
                    connectionTask      = _dbusConnectionTask;
                    _state = ConnectionState.Connecting;

                    EmitConnectionStateChanged();
                }
            }

            if (alreadyConnecting)
            {
                return(await connectionTask);
            }

            DBusConnection connection;
            object         disposeUserToken = NoDispose;

            try
            {
                ClientSetupResult connectionContext = await _connectFunction();

                disposeUserToken = connectionContext.TeardownToken;
                connection       = await DBusConnection.ConnectAsync(connectionContext, OnDisconnect, _connectCts.Token);
            }
            catch (ConnectException ce)
            {
                if (disposeUserToken != NoDispose)
                {
                    _disposeAction?.Invoke(disposeUserToken);
                }
                Disconnect(dispose: false, exception: ce);
                throw;
            }
            catch (Exception e)
            {
                if (disposeUserToken != NoDispose)
                {
                    _disposeAction?.Invoke(disposeUserToken);
                }
                var ce = new ConnectException(e.Message, e);
                Disconnect(dispose: false, exception: ce);
                throw ce;
            }
            lock (_gate)
            {
                if (_state == ConnectionState.Connecting)
                {
                    _disposeUserToken = disposeUserToken;
                    _dbusConnection   = connection;
                    _connectCts.Dispose();
                    _connectCts = null;
                    _state      = ConnectionState.Connected;
                    _dbusConnectionTcs.SetResult(connection);
                    _dbusConnectionTcs = null;

                    EmitConnectionStateChanged();
                }
                else
                {
                    connection.Dispose();
                    if (disposeUserToken != NoDispose)
                    {
                        _disposeAction?.Invoke(disposeUserToken);
                    }
                }
                ThrowIfNotConnected();
            }
            return(connection);
        }