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.
Assinar:
Postar comentários (Atom)

Nenhum comentário:
Postar um comentário