When the service is shutdown what is the correct way to terminate the
BeginPeek?
Since I saved the IAsyncResult from the BeginPeek and try to use that in a
call to EndPeek the call looks to be blocked. This call is in a try/catch but
never gets caught.
Since I am done with the queue I could just close the queue. But is that the
correct way to handle this situation?
--
Scott Norberg
The EndPeek() should always be called after BeginPeek() in PeekCompleted
event handler to read the actual message or try/catch an expected peeking
timeout exception(similar to BeginReceive/EndReceive ). You don't need to
call EndPeek() separately to terminate the peeking due to the MSMQ driver
will automatically terminate it after the service is shutdown.
The reason is that a thread which issued the async peek/receive operation
must be alive until the operation is completed by the msmq driver.
Otherwise, if the thread terminates, the operation will be cancelled by the
kernel.
MessageQueue..::.EndPeek Method
http://msdn.microsoft.com/en-us/library/system.messaging.messagequeue.endpee
k.aspx
Please let me know if you have any further question on this.
Have a nice week.
Sincerely,
WenJun Zhang
Microsoft Online Community Support
Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
msd...@microsoft.com.
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/en-us/subscriptions/aa948868.aspx#notifications.
Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://support.microsoft.com/select/default.aspx?target=assistance&ln=en-us.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
I know how Begin/End Peek work. But under certain conditions you may want to
stop a BeginPeek prior to receiving the next message on the queue. In this
application we have a Hold state that the queue can be put into, since MSMQ
has no such function we need to implement that ourselves. In this case I do
not want to terminate the underlying thread, I just want to stop the current
BeginPeek operation.
Don't try to solve my particular problem, I just want to know how to stop a
pending BeginPeek correctly! Aborting the underlying thread does not seem
like a good answer. Surely someone has wanted to do this.
--
Scott Norberg
The way I end Async Receive/Peek on MSMQ is to keep a bool property for
continuing. Also you need to make sure the BeginPeek is supplied with a
timeout. If you want to stop the application, set the boolean to false
and catch MessageQueueException in the callback. Only initiate a new
call to BeginPeek if the boolean is set to false.
E.g.
_messageQueue.BeginPeek(TimeSpan.FromSeconds(5), null, PeekCallback);
...
private void PeekCallback(IAsyncResult result)
{
try
{
Message message = _messageQueues.GetQueue(_queueType).EndPeek(result);
}
catch (MessageQueueException e)
{
if (e.MessageQueueErrorCode == MessageQueueErrorCode.IOTimeout)
{
// Do nothing
}
else
{
throw;
}
}
finally
{
if (_continueReceiving)
{
_messageQueue.BeginPeek(TimeSpan.FromSeconds(5), null, PeekCallback);
}
}
}
In the above example if _continueReceiving is set to false the next time
the callback occurs (either due to a message arriving or the timeout
occuring) the thread just dies.
Hope this is what you are looking for!
Neil
1. Only initiate a new call to BeginPeek if the boolean is set to TRUE
2. Message message = _messageQueues.GetQueue(_queueType).EndPeek(result);
SHOULD BE:
Message message = _messageQueues.EndPeek(result);
Sorry for confusion, I pasted this out of some of my own code.
Neil
That is the way I originally had the queue monitoring code written, but that
still leaves a timing window where the state of queue has changed and the
BeginPeek is still active. If there was a way to terminate the BeginPeek I
could stop that operation and then change queue state. Then I don't have to
load up the Peek event with state checking, even though it is not really a
lot of code. But I may still go back to that methodology.
Thanks for your sample. It is always interesting to see how other people
have solved some of the issues that you are currently working on. Sometimes
it just helps to know that you (me) are not going crazy. :-)
--
Scott Norberg
"Neil Alderson" wrote:
> Hi Scott,
>
> The way I end Async Receive/Peek on MSMQ is to keep a bool property for
> continuing. Also you need to make sure the BeginPeek is supplied with a
> timeout. If you want to stop the application, set the boolean to false
> and catch MessageQueueException in the callback. Only initiate a new
> call to BeginPeek if the boolean is set to false.
>
> E.g.
>
> _messageQueue.BeginPeek(TimeSpan.FromSeconds(5), null, PeekCallback);
>
> ....
In what way do you expect the state of the queue to change during a
BeginPeek?
Neil
According to your orginal question:
"When the service is shutdown what is the correct way to terminate the
BeginPeek?"
what I'd like to explain is it isn't necessary to explictly terminate the
BeginPeek operation, MSMQ will do this by itself. When your application
process or a single thread which perform the peeking operation is aborted,
the kernel MSMQ driver will detect it immediately and cancel the current
peeking request. So developers save the time on writing code to manage
unfinished peeking/receiving.
Please let me know if you have any further concern on this.
Thanks.
I confused that you only want to know how to stop a pending peeking when
the service is shutdown(not necessary). I'm sorry for that.
Closing the queue does help on terminating the current asynchronous
peeking/receiving operation. However this may occasionally stop working and
a PeekCompleted event will still be fired when new message arrives. This is
because MSMQ connection caching is enabled by default. The Close method of
MessageQueue object does not close the actual queue handle in this case. To
work around the behavior and force, you can either disable the connection
cache during the queue object creation:
MessageQueue.EnableConnectionCache = false;
or call MessageQueue.ClearConnectionCache() to clear up the connection
cache (replace MessageQueue.Close()) .
Some more detailed information on the caching behavior is documented in
below article:
842042 You may receive an "Invalid handle" error message if you remotely
read messages or if you remotely send messages by using Message Queuing
with a .NET application
http://support.microsoft.com/default.aspx?scid=kb;EN-US;842042
I hope the information helps. Please understand we always try our best to
be of assistance and you are always welcome in MSDN newsgroup. Thanks.