<?xml version="1.0" encoding="UTF-8"?><item><title>MSMQ, MessageQueue.Receive, and Thread.Abort</title><description>&lt;P&gt;Using MSMQ in a .NET app is incredibly easy - the framework does most of the grunt work for you.&amp;nbsp; Something that seems fairly natural is to use MSMQ in a Service.&lt;/P&gt;&#13;
&lt;P&gt;Services are controlled by the Service Control Manager.&amp;nbsp; When you say &amp;#8220;net start myservice&amp;#8221;, assuming MyService is installed with the SCM, your service is invoked, and is expected to contact the SCM and wait for commands.&amp;nbsp; This is handled by the framework so that all you have to do is implement OnStart and OnStop.&lt;/P&gt;&#13;
&lt;P&gt;Typically OnStart starts a thread, and OnStop signals the thread to stop.&amp;nbsp; An easy way to signal the thread to stop is to call Thread.Abort on the thread - this raises a ThreadAbortException, which is an exception that can't be suppressed - you can catch it, but when your catch scope ends, the CLR just throws it again, all the way out until your thread exits.&lt;/P&gt;&#13;
&lt;P&gt;This is somewhat dangerous obviously (since you can get interrupted anywhere), but if your exception handling is robust then you should be fine, and it's very easy to implement.&lt;/P&gt;&#13;
&lt;P&gt;The bummer is that if the purpose of your thread is to receive messages from a MessageQueue and process them, then you're probably blocking in MessageQueue.Receive.&amp;nbsp; This is not a .NET function, and Thread.Abort has no effect on it.&lt;/P&gt;&#13;
&lt;P&gt;You could call MessageQueue.Receive with a timeout, but instead of simply returning failure, the runtime actually throws an exception when the timeout expires - meaning you'd be constantly throwing exceptions as part of your normal operation, something to avoid.&lt;/P&gt;&#13;
&lt;P&gt;So here's what you do&lt;/P&gt;&lt;FONT size=1&gt;&#13;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;&#13;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;IAsyncResult result = queue.BeginReceive();&lt;BR&gt;result.AsyncWaitHandle.WaitOne();&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff&gt;return&lt;/FONT&gt; queue.EndReceive(result);&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&#13;
&lt;P dir=ltr&gt;Now instead of blocking inside the MessageQueue.Receive function, you're blocking in WaitOne, which will be woken up by the Thread.Abort.&lt;/P&gt;&#13;
&lt;P dir=ltr&gt;&amp;nbsp;&lt;/P&gt;</description><pubDate>Thu, 01 Sep 2005 19:17:07 GMT</pubDate></item>