private async Task EnqueueMessageWithCapacity(MessageArgs <TMessage> msg)
        {
            if (m_messageCollection.TryAdd(msg) || FullBehaviour == QueueFullBehaviour.AbandonNew)
            {
                return;
            }

            if (FullBehaviour == QueueFullBehaviour.BlockPublisher)
            {
                await m_messageCollection.AddAsync(msg);

                return;
            }

#if DEBUG
            System.Diagnostics.Contracts.Contract.Assert(FullBehaviour == QueueFullBehaviour.RemoveOldest,
                                                         "FullBehaviour should be QueueFullBehaviour.RemoveOldest");
#endif
            // 尝试获取空位, 不成功时进入循环体
            while (!(m_messageCollection.TryAdd(msg)))
            {
                // 获取空位失败, 尝试移除队首元素
                m_messageCollection.TryTake(out _);
            }
        }
        /// <summary>
        /// 向使用指定路由键<paramref name="key"/>注册的订阅者发布消息
        /// </summary>
        /// <param name="key">路由key</param>
        /// <param name="message">消息对象</param>
        /// <exception cref="ArgumentNullException"><paramref name="message"/>为空</exception>
        public async Task <MessagePublishResult> PublishMessageAsync(string key, TMessage message)
        {
            if (message == null)
            {
                throw new ArgumentNullException(nameof(message));
            }

            if (key == null)
            {
                throw new ArgumentNullException(nameof(key));
            }

            if (!m_subscribers.TryGetValue(key, out var handlers) ||
                handlers.Count == 0)
            {
                return(MessagePublishResult.None);
            }

            var result = new MessagePublishResult
            {
                ReceiverCount = (uint)handlers.Count
            };
            var bindings = new[] { key };

            try
            {
                var subscribers = handlers
                                  .Select(func =>
                {
                    var msgArgs = new MessageArgs <TMessage>(
                        this, key,
                        new ReadOnlyCollection <string>(bindings),
                        message);

                    return(Task.Run(() => func(msgArgs)));
                })
                                  .ToArray();

                await Task.WhenAll(subscribers);
            }
            catch (Exception e)
            {
                result.Exception = e;
            }

            return(result);
        }
        /// <summary>
        /// 向使用指定路由键<paramref name="key"/>注册的订阅者发布消息
        /// </summary>
        /// <param name="key">路由key</param>
        /// <param name="message">消息对象</param>
        /// <exception cref="ArgumentNullException"><paramref name="message"/>为空</exception>
        public async Task <MessagePublishResult> PublishMessageAsync(string key, TMessage message)
        {
            if (message == null)
            {
                throw new ArgumentNullException(nameof(message));
            }
            if (key == null)
            {
                throw new ArgumentNullException(nameof(key));
            }

            var handlers = m_handlers
                           .ToArray();

            if (handlers.Length == 0)
            {
                return(MessagePublishResult.None);
            }

            var result = new MessagePublishResult();

            try
            {
                var subscribers = handlers
                                  .Where(pair => pair.Value.Count > 0)
                                  .Select(pair =>
                {
                    var msgArgs = new MessageArgs <TMessage>(
                        this, key,
                        pair.Value,
                        message);

                    return(Task.Run(() => pair.Key(msgArgs)));
                })
                                  .ToArray();

                result.ReceiverCount = (uint)subscribers.Length;
                await Task.WhenAll(subscribers);
            }
            catch (Exception e)
            {
                result.Exception = e;
            }

            return(result);
        }
 /// <summary>
 /// 尝试获取队列中的消息, 如果队列中没有消息, 则立即返回false
 /// </summary>
 /// <param name="message"></param>
 /// <returns></returns>
 public bool TryTakeMessage(out MessageArgs <TMessage> message)
 {
     return(m_messageCollection.TryTake(out message));
 }