Пример #1
0
        /// <summary>
        /// Asynchronously deregisters a handler.
        /// </summary>
        /// <param name="handlerFactory">The handler to deregister.</param>
        /// <returns>
        /// A task representing the asynchronous operation.
        /// The value of the <see cref="Task{TResult}.Result"/> parameter contains a boolean value
        /// indicating whether the handler was actually found and deregistered.
        /// </returns>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="handlerFactory"/> is null.</exception>
        public async Task <bool> DeregisterAsync(IContextualProvider <THandler> handlerFactory)
        {
            if (handlerFactory == null)
            {
                throw new ArgumentNullException(nameof(handlerFactory));
            }

            Debug.Assert(_handlerStack != null);
            Debug.Assert(_lock != null);

            using (await _lock.LockAsync())
            {
                if (_handlerStack.IsEmpty)
                {
                    return(false);
                }

                var tos = _handlerStack.Last();

                Debug.Assert(tos != null);

                if (handlerFactory.Equals(tos))
                {
                    if (handlerFactory is IDeactivationNotifyable deactivationNotifyable)
                    {
                        await deactivationNotifyable.NotifyDeactivationAsync();
                    }

                    // Handler stack will be empty afterwards
                    if (_handlerStack.Count == 1)
                    {
                        await _dispatchForwarding.UnregisterForwardingAsync();
                    }
                    else if (_handlerStack[_handlerStack.Count - 2] is IActivationNotifyable activationNotifable)
                    {
                        await activationNotifable.NotifyActivationAsync();
                    }

                    _handlerStack = _handlerStack.RemoveAt(_handlerStack.Count - 1);

                    return(true);
                }

                var newStack = _handlerStack.Remove(handlerFactory);

                if (newStack == _handlerStack)
                {
                    return(false);
                }

                _handlerStack = newStack;
                return(true);
            }
        }
Пример #2
0
        /// <summary>
        /// Asynchronously deregisters a handler.
        /// </summary>
        /// <param name="handlerFactory">The handler to deregister.</param>
        /// <returns>
        /// A task representing the asynchronous operation.
        /// The value of the <see cref="Task{TResult}.Result"/> parameter contains a boolean value
        /// indicating whether the handler was actually found and deregistered.
        /// </returns>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="handlerFactory"/> is null.</exception>
        public async Task <bool> DeregisterAsync(IContextualProvider <THandler> handlerFactory)
        {
            if (handlerFactory == null)
            {
                throw new ArgumentNullException(nameof(handlerFactory));
            }

            Debug.Assert(_handlers != null);
            Debug.Assert(_lock != null);

            using (await _lock.LockAsync())
            {
                if (!_handlers.Contains(handlerFactory))
                {
                    return(false);
                }

                var handlers = _handlers.Remove(handlerFactory);

                if (handlers.IsEmpty)
                {
                    await _dispatchForwarding.UnregisterForwardingAsync();
                }

                if (handlers.IsEmpty && handlerFactory is IDeactivationNotifyable deactivationNotifyable)
                {
                    await deactivationNotifyable.NotifyDeactivationAsync();
                }

                _handlers = handlers;

                if (_handlers.Count == 1 && _handlers.First() is IActivationNotifyable activationNotifyable)
                {
                    await activationNotifyable.NotifyActivationAsync();
                }
                return(true);
            }
        }