public virtual void Dispatch(MessageDispatch dispatch)
{
MessageListener listener = this.listener;
try
{
lock(this.unconsumedMessages.SyncRoot)
{
if(this.clearDispatchList)
{
// we are reconnecting so lets flush the in progress messages
this.clearDispatchList = false;
this.unconsumedMessages.Clear();
if(this.pendingAck != null && this.pendingAck.AckType == (byte) AckType.DeliveredAck)
{
// on resumption a pending delivered ack will be out of sync with
// re-deliveries.
if(Tracer.IsDebugEnabled)
{
Tracer.Debug("removing pending delivered ack on transport interupt: " + pendingAck);
}
this.pendingAck = null;
}
}
if(!this.unconsumedMessages.Closed)
{
if(listener != null && this.unconsumedMessages.Running)
{
ActiveMQMessage message = CreateActiveMQMessage(dispatch);
this.BeforeMessageIsConsumed(dispatch);
try
{
bool expired = (!IgnoreExpiration && message.IsExpired());
if(!expired)
{
listener(message);
}
this.AfterMessageIsConsumed(dispatch, expired);
}
catch(Exception e)
{
if(IsAutoAcknowledgeBatch || IsAutoAcknowledgeEach || IsIndividualAcknowledge)
{
// Redeliver the message
}
else
{
// Transacted or Client ack: Deliver the next message.
this.AfterMessageIsConsumed(dispatch, false);
}
Tracer.Error(this.info.ConsumerId + " Exception while processing message: " + e);
// If aborted we stop the abort here and let normal processing resume.
// This allows the session to shutdown normally and ack all messages
// that have outstanding acks in this consumer.
if( (Thread.CurrentThread.ThreadState & ThreadState.AbortRequested) == ThreadState.AbortRequested)
{
Thread.ResetAbort();
}
}
}
else
{
this.unconsumedMessages.Enqueue(dispatch);
}
}
}
if(++dispatchedCount % 1000 == 0)
{
dispatchedCount = 0;
Thread.Sleep(1);
}
}
catch(Exception e)
{
this.session.Connection.OnSessionException(this.session, e);
}
}