private void HandleSingleMessageAsync(SingleMessageDisptaching singleMessageDispatching, IMessageHandlerProxy1 handlerProxy, string handlerTypeName, string messageTypeName, QueuedHandler <IMessageHandlerProxy1> queueHandler, int retryTimes)
        {
            var message = singleMessageDispatching.Message;

            _ioHelper.TryAsyncActionRecursively("HandleSingleMessageAsync",
                                                () => handlerProxy.HandleAsync(message),
                                                currentRetryTimes => HandleSingleMessageAsync(singleMessageDispatching, handlerProxy, handlerTypeName, messageTypeName, queueHandler, currentRetryTimes),
                                                result =>
            {
                singleMessageDispatching.RemoveHandledHandler(handlerTypeName);
                if (queueHandler != null)
                {
                    queueHandler.OnHandlerFinished(handlerProxy);
                }
                if (_logger.IsDebugEnabled)
                {
                    _logger.DebugFormat("Message handled success, handlerType:{0}, messageType:{1}, messageId:{2}", handlerTypeName, message.GetType().Name, message.Id);
                }
            },
                                                () => string.Format("[messageId:{0}, messageType:{1}, handlerType:{2}]", message.Id, message.GetType().Name, handlerProxy.GetInnerObject().GetType().Name),
                                                errorMessage =>
            {
                _logger.Fatal(string.Format("Handle single message has unknown exception, the code should not be run to here, errorMessage: {0}", errorMessage));
            },
                                                retryTimes);
        }
        private void DispatchSingleMessage(IMessage message, QueueMessageDisptaching queueMessageDispatching)
        {
            var messageHandlerDataList = _handlerProvider.GetHandlers(message.GetType());

            if (!messageHandlerDataList.Any())
            {
                queueMessageDispatching.OnMessageHandled(message);
                return;
            }

            foreach (var messageHandlerData in messageHandlerDataList)
            {
                var singleMessageDispatching = new SingleMessageDisptaching(message, queueMessageDispatching, messageHandlerData.AllHandlers, _typeNameProvider);

                if (messageHandlerData.ListHandlers != null && messageHandlerData.ListHandlers.IsNotEmpty())
                {
                    foreach (var handler in messageHandlerData.ListHandlers)
                    {
                        DispatchSingleMessageToHandlerAsync(singleMessageDispatching, handler, null, 0);
                    }
                }
                if (messageHandlerData.QueuedHandlers != null && messageHandlerData.QueuedHandlers.IsNotEmpty())
                {
                    var queueHandler = new QueuedHandler <IMessageHandlerProxy1>(messageHandlerData.QueuedHandlers, (queuedHandler, nextHandler) => DispatchSingleMessageToHandlerAsync(singleMessageDispatching, nextHandler, queuedHandler, 0));
                    DispatchSingleMessageToHandlerAsync(singleMessageDispatching, queueHandler.DequeueHandler(), queueHandler, 0);
                }
            }
        }
        private void HandleSingleMessageAsync(SingleMessageDisptaching singleMessageDispatching, IMessageHandlerProxy1 handlerProxy, string handlerTypeName, string messageTypeName, QueuedHandler <IMessageHandlerProxy1> queueHandler, int retryTimes)
        {
            var message = singleMessageDispatching.Message;

            _ioHelper.TryAsyncActionRecursively <AsyncTaskResult>("HandleSingleMessageAsync",
                                                                  () => handlerProxy.HandleAsync(message),
                                                                  currentRetryTimes => HandleSingleMessageAsync(singleMessageDispatching, handlerProxy, handlerTypeName, messageTypeName, queueHandler, currentRetryTimes),
                                                                  result =>
            {
                var messageHandleRecord = new MessageHandleRecord
                {
                    MessageId       = message.Id,
                    MessageTypeName = messageTypeName,
                    HandlerTypeName = handlerTypeName,
                    CreatedOn       = DateTime.Now
                };
                var sequenceMessage = message as ISequenceMessage;
                if (sequenceMessage != null)
                {
                    messageHandleRecord.AggregateRootTypeName = sequenceMessage.AggregateRootTypeName;
                    messageHandleRecord.AggregateRootId       = sequenceMessage.AggregateRootStringId;
                    messageHandleRecord.Version = sequenceMessage.Version;
                }

                AddMessageHandledRecordAsync(singleMessageDispatching, messageHandleRecord, handlerProxy.GetInnerObject().GetType(), handlerTypeName, handlerProxy, queueHandler, 0);
            },
                                                                  () => string.Format("[messageId:{0}, messageType:{1}, handlerType:{2}]", message.Id, message.GetType().Name, handlerProxy.GetInnerObject().GetType().Name),
                                                                  null,
                                                                  retryTimes,
                                                                  true);
        }
        private void DispatchSingleMessageToHandlerAsync(SingleMessageDisptaching singleMessageDispatching, IMessageHandlerProxy1 handlerProxy, QueuedHandler <IMessageHandlerProxy1> queueHandler, int retryTimes)
        {
            var message               = singleMessageDispatching.Message;
            var messageTypeName       = _typeNameProvider.GetTypeName(message.GetType());
            var handlerType           = handlerProxy.GetInnerObject().GetType();
            var handlerTypeName       = _typeNameProvider.GetTypeName(handlerType);
            var aggregateRootTypeName = message is ISequenceMessage ? ((ISequenceMessage)message).AggregateRootTypeName : null;

            _ioHelper.TryAsyncActionRecursively <AsyncTaskResult <bool> >("IsRecordExistAsync",
                                                                          () => _messageHandleRecordStore.IsRecordExistAsync(message.Id, handlerTypeName, aggregateRootTypeName),
                                                                          currentRetryTimes => DispatchSingleMessageToHandlerAsync(singleMessageDispatching, handlerProxy, queueHandler, currentRetryTimes),
                                                                          result =>
            {
                if (result.Data)
                {
                    singleMessageDispatching.RemoveHandledHandler(handlerTypeName);
                    if (queueHandler != null)
                    {
                        queueHandler.OnHandlerFinished(handlerProxy);
                    }
                }
                else
                {
                    HandleSingleMessageAsync(singleMessageDispatching, handlerProxy, handlerTypeName, handlerTypeName, queueHandler, 0);
                }
            },
                                                                          () => string.Format("[messageId:{0}, messageType:{1}, handlerType:{2}]", message.Id, message.GetType().Name, handlerType.Name),
                                                                          null,
                                                                          retryTimes,
                                                                          true);
        }
        private void DispatchSingleMessageToHandlerAsync(SingleMessageDisptaching singleMessageDispatching, IMessageHandlerProxy1 handlerProxy, QueuedHandler <IMessageHandlerProxy1> queueHandler, int retryTimes)
        {
            var message         = singleMessageDispatching.Message;
            var messageTypeName = _typeNameProvider.GetTypeName(message.GetType());
            var handlerType     = handlerProxy.GetInnerObject().GetType();
            var handlerTypeName = _typeNameProvider.GetTypeName(handlerType);

            HandleSingleMessageAsync(singleMessageDispatching, handlerProxy, handlerTypeName, messageTypeName, queueHandler, 0);
        }
        private void HandleSingleMessageAsync(SingleMessageDisptaching singleMessageDispatching, IMessageHandlerProxy1 handlerProxy, string handlerTypeName, string messageTypeName, QueuedHandler <IMessageHandlerProxy1> queueHandler, int retryTimes)
        {
            var message = singleMessageDispatching.Message;

            _ioHelper.TryAsyncActionRecursivelyWithoutResult("HandleSingleMessageAsync",
                                                             () => handlerProxy.HandleAsync(message),
                                                             currentRetryTimes => HandleSingleMessageAsync(singleMessageDispatching, handlerProxy, handlerTypeName, messageTypeName, queueHandler, currentRetryTimes),
                                                             () =>
            {
                singleMessageDispatching.RemoveHandledHandler(handlerTypeName);
                if (queueHandler != null)
                {
                    queueHandler.OnHandlerFinished(handlerProxy);
                }
                _logger.DebugFormat("Message handled success, handlerType:{0}, messageType:{1}, messageId:{2}", handlerTypeName, message.GetType().Name, message.Id);
            },
                                                             () => string.Format("[messageId:{0}, messageType:{1}, handlerType:{2}]", message.Id, message.GetType().Name, handlerProxy.GetInnerObject().GetType().Name),
                                                             null,
                                                             retryTimes, true);
        }
        private void AddMessageHandledRecordAsync(SingleMessageDisptaching singleMessageDispatching, MessageHandleRecord messageHandleRecord, Type handlerType, string handlerTypeName, IMessageHandlerProxy1 handlerProxy, QueuedHandler <IMessageHandlerProxy1> queueHandler, int retryTimes)
        {
            var message = singleMessageDispatching.Message;

            _ioHelper.TryAsyncActionRecursively <AsyncTaskResult>("AddMessageHandledRecordAsync",
                                                                  () => _messageHandleRecordStore.AddRecordAsync(messageHandleRecord),
                                                                  currentRetryTimes => AddMessageHandledRecordAsync(singleMessageDispatching, messageHandleRecord, handlerType, handlerTypeName, handlerProxy, queueHandler, currentRetryTimes),
                                                                  result =>
            {
                singleMessageDispatching.RemoveHandledHandler(handlerTypeName);
                if (queueHandler != null)
                {
                    queueHandler.OnHandlerFinished(handlerProxy);
                }
                if (_logger.IsDebugEnabled)
                {
                    _logger.DebugFormat("Message handled success, handlerType:{0}, messageType:{1}, messageId:{2}", handlerType.Name, message.GetType().Name, message.Id);
                }
            },
                                                                  () => string.Format("[messageId:{0}, messageType:{1}, handlerType:{2}]", message.Id, message.GetType().Name, handlerType.Name),
                                                                  null,
                                                                  retryTimes,
                                                                  true);
        }