예제 #1
0
        /// <summary>
        /// <para>Deliver the message to the consumers selected in <see cref="ReceiveFromEndpoint"/>. Assumption:
        /// the inbound transport will send the same context to this method as it did
        /// to the lambda in <see cref="ReceiveFromEndpoint"/>.</para>
        /// <para>This method will try to give the message to all consumers found.</para>
        /// </summary>
        /// <param name="context">The receive context</param>
        /// <exception cref="MessageException">If at least one consumer throws
        /// an exception, then a MessageException will be thrown. If multiple consumers
        /// threw exceptions, then the last exception will be the inner exception
        /// and the others won't be tracked.</exception>
        void DeliverMessageToConsumers([NotNull] IReceiveContext context)
        {
            try
            {
                NotifyReceiveCompleted();

                _receiveTime.Stop();
                _consumeTime.Start();

                if (_log.IsDebugEnabled)
                {
                    _log.DebugFormat("Dispatching message on {0} from thread {1}", _bus.Endpoint.Address.Uri,
                                     Thread.CurrentThread.ManagedThreadId);
                }

                bool atLeastOneConsumerFailed = false;

                Exception lastException = null;

                do
                {
                    try
                    {
                        _consumers.Current(context);
                        _consumeCount++;
                    }
                    catch (Exception ex)
                    {
                        _log.Error(string.Format("'{0}' threw an exception consuming message '{1}'",
                                                 _consumers.Current.GetType().FullName,
                                                 context.GetType().FullName), ex);

                        atLeastOneConsumerFailed = true;
                        lastException            = ex;
                    }
                } while (_consumers.MoveNext());

                if (atLeastOneConsumerFailed)
                {
                    throw new MessageException(context.GetType(),
                                               "At least one consumer threw an exception",
                                               lastException);
                }
            }
            finally
            {
                _consumeTime.Stop();

                _consumers.Dispose();
                _consumers = null;

                ReportConsumerTime(_startTime, _receiveTime.Elapsed, _consumeTime.Elapsed, context);
                ReportConsumerCount(context, _consumeCount);
            }
        }
		void DeliverMessageToConsumers(IReceiveContext context)
		{
			try
			{
				NotifyReceiveCompleted();

				_receiveTime.Stop();
				_consumeTime.Start();

				if (_log.IsDebugEnabled)
					_log.DebugFormat("Dispatching message on {0} from thread {1}", _bus.Endpoint.Address.Uri,
						Thread.CurrentThread.ManagedThreadId);

				bool atLeastOneConsumerFailed = false;

				Exception lastException = null;

				do
				{
					try
					{
						_consumers.Current(context);
						_consumeCount++;
					}
					catch (Exception ex)
					{
						_log.Error(string.Format("'{0}' threw an exception consuming message '{1}'",
							_consumers.Current.GetType().FullName,
							context.GetType().FullName), ex);

						atLeastOneConsumerFailed = true;
						lastException = ex;
					}
				} while (_consumers.MoveNext());

				if (atLeastOneConsumerFailed)
				{
					throw new MessageException(context.GetType(),
						"At least one consumer threw an exception",
						lastException);
				}
			}
			finally
			{
				_consumeTime.Stop();

				_consumers.Dispose();
				_consumers = null;

				ReportConsumerTime(_startTime, _receiveTime.Elapsed, _consumeTime.Elapsed, context);
				ReportConsumerCount(context, _consumeCount);
			}
		}