You can refer to this article on the subject ...
http://msdn.microsoft.com/msdnmag/issues/05/10/WickedCode/
Sébastien
On 8/6/06, Paul Cowan <[EMAIL PROTECTED]> wrote:
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(r) http://www.develop.com
View archives and manage your subscription(s) at http://discuss.develop.com
--
Sébastien Lorion
Software Architect / Architecte organique
[EMAIL PROTECTED]
===================================
This list is hosted by DevelopMentor® http://www.develop.com
View archives and manage your subscription(s) at http://discuss.develop.com