Hi,
 I could actually do with some design advice on what I am trying to achieve 
with this MSMQ problem.  We are writing a web app. where unfortunately we have 
to deal with a product called Navision where by we have to communicate via 
MSMQ.  It's not the way I would have done it but there you go, this piece of 
the architecture cannot change.
As this MSMQ process might be quite time consuming, I want to take advantage of 
ASP.NET 2.0 asynchronous page’s functionality.  The problem I have is I am 
struggling with the whole asynchronous model.  As stands I have the web 
application that will call a component I have lovingly called the MSMQAdapter.  
The MSMQAdapter takes a domain object and takes care of placing the message on 
the queue and retrieving a response message from a different queue which are 
married together by CorrelationId.  If I was to do this synchronously, I have 
no problem with how to do this.  But asynchronously I am struggling.  The web 
app calls the following code in the MSMQAdapter:
public void CalculateOrder(ShoppingCart cart)
{
    try
    {
        OrderBuilder orderBuilder = new 
OrderBuilder(OrderBuilder.OrderMessage.CALCULATEORDER);
        MSMQHelper helper = new MSMQHelper();
        helper.Request(orderBuilder.Build(cart));
    }
    catch (Exception ex)
    {
        log.Error("MSMQHelper.Request", ex);
        throw ex;
    }
}
The request method looks like this:
public void Request(string xml)
{
_correlationId = SendMessage(xml);
_receiveQ = GetQueue(LawConfig.MSMQ.ReceiveMSMQ);
_receiveQ.MessageReadPropertyFilter.CorrelationId = true;
_receiveQ.PeekCompleted += new 
PeekCompletedEventHandler(ReceiveQ_PeekCompleted);
_receiveQ.BeginPeek(_timeOut);    
}
 
The ReceiveQ_PeekCompleted handler looks like this:
 
private void ReceiveQ_PeekCompleted(object sender, PeekCompletedEventArgs e)
{
       MessageQueue messageQueue = sender as MessageQueue;
       using (Message message = messageQueue.EndPeek(e.AsyncResult))
       {
           if (!message.CorrelationId.Equals(_correlationId))
           {
               messageQueue.BeginPeek(_timeOut);
               return;
           }
       }
       using (Message message = 
messageQueue.ReceiveByCorrelationId(_correlationId))
      {
            //DO processing
}
}
 
This method will do some calculation with the message and then I would like to 
return a domain object to the web application but I do not know how to do this? 
 How can I get the domain object back to the web application?  Do I have to 
raise some custom events in order to get back to the web application or is 
there a better way?  Is there a way I can call this method asynchronously from 
the web application?
 
Sorry for the length of this email but I am really stuck.
 
Cheers
 
Paul
 
 
[EMAIL PROTECTED]



> Date: Sun, 6 Aug 2006 10:07:08 +0000> From: [EMAIL PROTECTED]> Subject: Re: 
> [ADVANCED-DOTNET] ReceiveByCorrelationId + MSMQ> To: 
> [email protected]> > Hi,> Thanks for the help.  Is there a 
> way to take the message off the queue without calling ReceiveByCorrelationId 
> because behind the scenes that method iterates through every message in the 
> queue and then takes the message off the queue and I doubt it is thread 
> safe.>  > Thanks> [EMAIL PROTECTED]> > > > > Date: Sat, 5 Aug 2006 17:03:45 
> -0500> From: [EMAIL PROTECTED]> Subject: Re: [ADVANCED-DOTNET] 
> ReceiveByCorrelationId + MSMQ> To: [email protected]> > 
> Sample below...> > A few thoughts/comments - first, I think you always want 
> to EndPeek. I> remember reading somewhere that the API docs state that the 
> framework does> not promise to behave nicely if you forget to. Second, 
> EndPeek will throw an> exception if BeginPeek times out. I added the 'using' 
> statements on the> messages because they are disposable and I am a little 
> superstitutious about> that more than that I have ever actually seen that 
> cause a problem. It would> seem weird to me that a Message object would 
> actually hold on to some> important unmanaged resource, but who knows? 
> Reflector doesn't make it> obvious. Maybe someone can comment on that. FWIW, 
> I highly recommend you set> up a little functional test in NUnit or whatever 
> it is you use to write your> tests to simulate the situation you are looking 
> for and prove it out to> yourself. You don't even have to have Navision 
> running. There are few things> like the comfort of a good, green bar to aid 
> in understanding.> > I hope that helps!> > Thanks,> Jef Newsom> > > private 
> void ReceiveQ_PeekCompleted(object sender, PeekCompletedEventArgs e)> {>    
> try>    {>      MessageQueue messageQueue = sender as MessageQueue;>      
> using(Message message = messageQueue.EndPeek(e.AsyncResult))>      {>        
> if(!message.CorrelationId.Equals(_correlationId))>        {>           
> messageQueue.BeginPeek(_timeOut);>           return;>        }>      }>      
> using(message = messageQueue.ReceiveByCorrelationId(_correlationId))>      {> 
>        // do something with it.>      }>    }>    catch(MessageQueueException 
> e)>    {>      if(e.MessageQueueErrorCode == 
> MessageQueueErrorCode.IOTimeout*)*> *     {*>         // log it, peek again, 
> whatever you think is the right thing to do.>      }>    }> }> > > On 8/5/06, 
> Paul Cowan <[EMAIL PROTECTED]> wrote:> >> > Hi,> >> > THe eventargs contains 
> the message.  I have the following event handler> > for PeekCompleted:> >> > 
> private void ReceiveQ_PeekCompleted(object sender, PeekCompletedEventArgs> > 
> e)> > {> >    if (e.Message.CorrelationId != _correlationId)> >    {> >       
>   messageQueue.BeginPeek(_timeOut);> >         return;> >    }> >    
> MessageQueue messageQueue = sender as MessageQueue;> >    Message message = 
> messageQueue.EndPeek(e.AsyncResult);> > }> >> > My question is what if there 
> is an error on the other side and the message> > never gets placed onto the 
> queue??  How can I timeout gracefully if> > BeginPeek is being called each 
> time?> >> > Thanks> > Paul> > [EMAIL PROTECTED]> >> >> >> > > Date: Sat, 5 
> Aug 2006 14:16:28 -0500> From: [EMAIL PROTECTED]>> > Subject: Re: 
> [ADVANCED-DOTNET] Recei
===================================
This list is hosted by DevelopMentor®  http://www.develop.com

View archives and manage your subscription(s) at http://discuss.develop.com

Reply via email to