How to manage a remote MessageQueue restarting?

F

felecha

I'm stumped. I'm working on an application in VB.Net that uses
System.Messaging.MessageQueue to listen for messages sent to a
private queue on a remote machine. Both machines are in the same
Workgroup in a small private LAN. The messaging is working fine, but
since the remote machine is used as a control system and has to be
rebooted when there is a configuration change, I have to handle the
remote queue going down and coming back up again. My application is
on the "local" machine, listening for messages and processing them
for a user interface.

I just can't figure out how to do that. I'm learning about
MessageQueue from the .Net Help and MSDN documentation and stuff I
can find on the internet. It looks like if I just keep the same
local MessageQueue object listening, it doesn't connect to the new
remote queue. I have to make a new MessageQueue on the local
machine, with a new handle.

If I kill the Message Queuing service on the remote machine, I can
detect that - it throws exceptions in the EndReceive method in my
ReceiveCompleted handler. But the real behavior is going to be
restarting the remote system, and when I try to mimic that on my
development machines, nothing happens in my local application. I've
tried using tests based on MessageQueue.Exists() but it seems that
the method doesn't work for remote machines in a Workgroup setting.
I thought maybe the CanRead() method would tell me if the remote
queue was "alive". I did a repeating timed loop that kept calling
CanRead(), but it kept returning TRUE all the way through the remote
machine's restart.

Any clues? There must be some documentation somewhere. People must
have to deal with this in their applications.
 
F

felecha

Well, it's getting more interesting. I was working on it over the
weekend, using my home desktop and laptop as the development
environment. Both run Windows 2000 Pro. Now I'm at work, where I
work on an XP Pro machine and have both my laptop and another
development machine with XP. I've discovered that if the remote
queue is on the XP machine, the ReceiveCompleted event seems to be
raised as soon as the remote queue goes down, and the EndReceive
method in the handler throws an exception. But if the remote queue
is on the laptop nothing happens until a long time later - as long as
15 minutes after the restart, the event and the exceptions started.

It turns out that the remote machine is going to be running Windows
2000 in the field, so now that I've found there are differences in
behavior, I have to find out the specifics of 2000 behavior.

I thought I would play around with putting a button on a form that
would just re-instantiate the MessageQueue object on the local
machine and let it re-connect to the restarted queue, and if that
works I would use that as a basis for my solution. But now I'm
finding that the local MessageQueue object is very inconsistent in
being able to find and connect to the remote queue.

I thought maybe I would try to Delete() the remote queue and then
Create() it new, but in a WorkGroup setting it turns out those
methods don't work at all.

Does anyone know about the details of how a MessageQueue running in an
application on an XP machine interacts with a queue on a 2000
machine? I'm running out of ideas to try.

Surely this must have been solved by someone at some time somewhere in
the world. I can't find any clues at MSDN, either

Here's hoping
 
F

felecha

Still can't find the answer, but there are more clues. I've studied
and dug more into it, and got some coaching from a guy who has lots
of experience with threading but none with MessageQueues. He has
looked at it and thinks the problem is with the callback that the
BeginReceive() method creates. Apparently when a remote XP system
goes down, any pending callback correctly comes back to the
ReceiveCompleted handler and completes the operation, so that when
the remote comes up again it's ready to reconnect with a simple
re-instantiation of the local MessageQueue object that listens to it.
But a 2000 system is not doing that, and leaves something hung up or
blocked and when the remote 2000 queue comes back, a new MessageQueue
object on the local machine can't make the re-connection and throws
exceptions. And what is really interesting is that if I separately
open the Windows Services from Control Panel and restart the Message
Queuing service, the next time I re-instantiate the local
MessageQueue object listening to the 2000 queue, it connects and
fetches any messages held in the queue there. I've already learned
that in general I have to clear the connection cache when I
reinstantiate MessageQueues, but there must be something else that is
"inside the system" somewhere in MessageQueuing, that gets
"refreshed" by restarting the Service, so now a new MessageQueue
object can make a new connection. Just an idea, and I don't know how
to go further with it.

Again, it's a clear difference in the way that MSMQ works on a 2000
system.

I learned that I could call BeginReceive with a timeout argument, and
I thought that that would take care of returning from a callback if
the remote queue went down, but it still doesn't solve it.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top