Beispiel #1
0
        private void Connection_ConnectionStateChanged(object sender, ConnectionStateChangedEventArgs e)
        {
            switch (e.NewState)
            {
            case ConnectionState.Closed:
                RemoveConnection(e.Connection);
                break;
            }

            ConnectionStateChanged?.Invoke(this, e);
        }
Beispiel #2
0
        /// <summary>
        /// Transition from the current <see cref="ConnectionState"/> to the <paramref name="newState"/>.
        /// Returns true if the state was transitioned.
        /// If the transition is invalid, <see cref="TransitionInvalidException"/> will be thrown.
        /// </summary>
        /// <param name="newState">The new state to transition to.</param>
        /// <exception cref="InvalidOperationException">If the transition is not valid (determined by <see cref="IsStateTransitionValid(ConnectionState, ConnectionState, bool)"/>)</exception>
        protected bool TransitionState(ConnectionState newState)
        {
            var args = new ConnectionStateChangedEventArgs {
                Connection = this,
                NewState   = newState,
            };

            bool stateTransitioned = false;

            lock (_stateLocker) {
                ConnectionState oldState = State;

                // The state didn't transition.
                if (oldState == newState)
                {
                    return(false);
                }

                if (!IsStateTransitionValid(oldState, newState))
                {
                    throw new TransitionInvalidException(oldState, newState);
                }

                // The transition is valid, lets continue.

                // Have to set this in the lock statement in case the value changed
                args.OldState = oldState;

                // Set the new state
                _state = newState;

                stateTransitioned = oldState != _state;
            }

            if (stateTransitioned)
            {
                OnConnectionStateChanged(this, args);
            }

            return(stateTransitioned);
        }
Beispiel #3
0
        protected virtual void OnConnectionStateChanged(object sender, ConnectionStateChangedEventArgs args)
        {
            using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(1))) {
                try {
                    Task.Run(() => {
                        ConnectionStateChanged?.Invoke(this, args);
                    }, cts.Token).GetAwaiter().GetResult();
                } catch (TaskCanceledException) {
                    throw new InvalidOperationException("Deadlock detected");
                }
            }

            if (args.NewState == ConnectionState.Closed)
            {
                try {
                    _closedCancellation?.Cancel();
                } catch (ObjectDisposedException) {
                    Log.Info($"{this}: {nameof(TransitionState)}: close cancellation disposed");
                }
            }
        }