quinta-feira, 5 de novembro de 2009

Revisão da função de leitura de mensagens da classe genérica de acesso ao MSMQ.

Dei uma revisada nas funções que usei no artigo anterior, agora ficou mais enxuto:


private Message obtemMensagem(MessageEnumerator msmqEnumerator,
MessageQueueTransaction msmqTransacao)
{
Message msmqRetorno;
if (msmqTransacao != null)
msmqRetorno = msmqEnumerator.RemoveCurrent(msmqTransacao);
else
msmqRetorno = msmqEnumerator.RemoveCurrent();
return msmqRetorno;

}


A função acima faz uso diretamente do RemoveCurrent, que já devolve a mensagem corrente do MessageEnumerator.

No método de leitura, um pouco de revisão não faz mal a ninguém:


public void receberMensagens(MSMQProcessaOcorrencia metodoProcessar)
{
MessageQueue msmqFila = null;
MessageQueueTransaction msmqTransacao = null;
MessageEnumerator msmqEnumerator = null;
bool retornoProcessamento = false;

try
{
msmqFila = new MessageQueue(this.NomeFila);
msmqFila.Formatter = new ActiveXMessageFormatter();
msmqFila.MessageReadPropertyFilter.SetAll();
msmqEnumerator = msmqFila.GetMessageEnumerator2();

if (msmqEnumerator.MoveNext())
{
while (msmqEnumerator.Current != null)
{
retornoProcessamento = false;
try
{

if (this.Transacional)
{
msmqTransacao = new MessageQueueTransaction();
msmqTransacao.Begin();
}

Message msmqMensagemCorrente = this.obtemMensagem(msmqEnumerator, msmqTransacao);
if (msmqMensagemCorrente == null) continue;
retornoProcessamento = (metodoProcessar != null) ? metodoProcessar(msmqMensagemCorrente) : true;

}
catch (Exception)
{
retornoProcessamento = false;
}
finally
{
if (this.Transacional)
{
if (retornoProcessamento) msmqTransacao.Commit();
else msmqTransacao.Abort();
msmqTransacao = null;
}
}

}
}

}
catch (MessageQueueException erro)
{
if (erro.MessageQueueErrorCode != MessageQueueErrorCode.IOTimeout)
throw erro;
}
catch (Exception erro)
{
throw erro;
}
finally
{
if (msmqTransacao != null) msmqTransacao.Abort();
if (msmqFila != null) msmqFila.Close();
}

}



O tratamento da MessageQueueException, ignorando quando é MessageQueueErrorCode.IOTimeout, é imprescindível, para que a rotina chamadora não tenha uma profusão de erros ocasionados pela leitura da propriedade MessageQueueEnumerator.Current, que retorna esta exception quando terminamos de varrer o enumerator inteiro.

Nenhum comentário:

Postar um comentário