|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
MSMQ & Multithreadingmessage queue and do some processing on them; the application is multithreaded, and each thread runs in a loop receving a message, processing it and so on; the loop is controlled by a flag, if this flag becomes to true the thread exits. To stop the application, the controller thread sets the flag to true and calls Thread.Interrupt() on each thread... but this doesn't seem to stop the thread if it's blocked on a MessageQueue.Receive() operation. Why is this? And how can I solve this problem? Someone suggested using a two-part loop, having the thread sleep for a while and then check the message queue with a short timeout; this way, the thread can be interrupted. But this seems a lot inefficient to me. Any ideas? Thanks Massimo "Massimo" <bar***@mclink.it> wrote in message Apparently MessageQueue.Receive blocks outside the CLR. Thread.Interrupt news:uICiVYZ6GHA.3952@TK2MSFTNGP04.phx.gbl... > I'm writing a .NET (2.0) application than needs to receive messages from a > message queue and do some processing on them; the application is > multithreaded, and each thread runs in a loop receving a message, > processing it and so on; the loop is controlled by a flag, if this flag > becomes to true the thread exits. > > To stop the application, the controller thread sets the flag to true and > calls Thread.Interrupt() on each thread... but this doesn't seem to stop > the thread if it's blocked on a MessageQueue.Receive() operation. > > Why is this? can only wake up a thread that's blocked inside the CLR. > And how can I solve this problem? I would expect that simply closing the queue will cause those threads blocked in reads to wake up with an error. > Another approach is rather than sleep, have the thread call one of the > Someone suggested using a two-part loop, having the thread sleep for a > while and then check the message queue with a short timeout; this way, the > thread can be interrupted. But this seems a lot inefficient to me. overloads of Receive that takes a timeout. When a timeout occurs, check the terminate flag and end the thread if appropriate. Yes, this is somewhat inefficient, but it may be acceptable depending on your particular needs. All in all, you're probably better off re-architecting your solution. Have a single thread call Receive (or BeginReceive) on the queue, and when it gets a message pass it off to the thread pool for processing. -cd "Carl Daniel [VC++ MVP]" <cpdaniel_remove_this_and_nospam@mvps.org.nospam> I was fearing something like that :-/ha scritto nel messaggio news:eBrmwdZ6GHA.2120@TK2MSFTNGP03.phx.gbl... > Apparently MessageQueue.Receive blocks outside the CLR. Thread.Interrupt > can only wake up a thread that's blocked inside the CLR. >> And how can I solve this problem? Will it disable and/or delete the queue itself? There's another application > > I would expect that simply closing the queue will cause those threads > blocked in reads to wake up with an error. sending messages to it, and it needs the queue even if this one stops. > Another approach is rather than sleep, have the thread call one of the I'll probably do something like that; I just didn't want the threads to run > overloads of Receive that takes a timeout. When a timeout occurs, check > the terminate flag and end the thread if appropriate. > > Yes, this is somewhat inefficient, but it may be acceptable depending on > your particular needs. when there are no messages to process. > All in all, you're probably better off re-architecting your solution. That wouldn't solve the problem of stopping this single thread :-)> Have a single thread call Receive (or BeginReceive) on the queue, and when > it gets a message pass it off to the thread pool for processing. Massimo You have to make the .Receive or .Peek .. and use a TimeSpan period. (aka,
use the overloaded version of Receive or .Peek. The TimeSpan for (the 2 items above) needs to be less....... then the TimeSpan you use when you call the Thread.Interupt or Thread.Abort() (these have a TimeSpan overload also) ... Then, you have the catch the specific MSMQException, and the Timeout period. Here is where you check your flag, and exit out. You have to remember that msmq is COM stuff, and thus happens outside the ..Net world. Thus the Thread.Interupt or .Abort doesn't affect it as you might think it would. Show quote "Massimo" <bar***@mclink.it> wrote in message news:uICiVYZ6GHA.3952@TK2MSFTNGP04.phx.gbl... > I'm writing a .NET (2.0) application than needs to receive messages from a > message queue and do some processing on them; the application is > multithreaded, and each thread runs in a loop receving a message, processing > it and so on; the loop is controlled by a flag, if this flag becomes to true > the thread exits. > > To stop the application, the controller thread sets the flag to true and > calls Thread.Interrupt() on each thread... but this doesn't seem to stop the > thread if it's blocked on a MessageQueue.Receive() operation. > > Why is this? > And how can I solve this problem? > > Someone suggested using a two-part loop, having the thread sleep for a while > and then check the message queue with a short timeout; this way, the thread > can be interrupted. But this seems a lot inefficient to me. > > Any ideas? > > Thanks > > > Massimo > Another solution to this problem is to send a custom Quit message to the
message q then exit when this particular message is received. Show quote "Massimo" wrote: > I'm writing a .NET (2.0) application than needs to receive messages from a > message queue and do some processing on them; the application is > multithreaded, and each thread runs in a loop receving a message, processing > it and so on; the loop is controlled by a flag, if this flag becomes to true > the thread exits. > > To stop the application, the controller thread sets the flag to true and > calls Thread.Interrupt() on each thread... but this doesn't seem to stop the > thread if it's blocked on a MessageQueue.Receive() operation. > > Why is this? > And how can I solve this problem? > > Someone suggested using a two-part loop, having the thread sleep for a while > and then check the message queue with a short timeout; this way, the thread > can be interrupted. But this seems a lot inefficient to me. > > Any ideas? > > Thanks > > > Massimo > > "Massimo" <bar***@mclink.it> wrote in message Why are you running threads like this?news:uICiVYZ6GHA.3952@TK2MSFTNGP04.phx.gbl... > I'm writing a .NET (2.0) application than needs to receive messages from a > message queue and do some processing on them; the application is > multithreaded, and each thread runs in a loop receving a message, > processing it and so on; the loop is controlled by a flag, if this flag > becomes to true the thread exits. > > To stop the application, the controller thread sets the flag to true and > calls Thread.Interrupt() on each thread... but this doesn't seem to stop > the thread if it's blocked on a MessageQueue.Receive() operation. > If they are all processing the same queue why not use the AsyncReceive? Then you get the benefit of when the app starts shutting down the Async calls all come back with Errors that the Queue is closed. You would not need to test for quit, just close the Queue and all the Async operations will come back to their calling app. |
|||||||||||||||||||||||