Is here a way to signal to the MSMQ to unblock subscribers which are blocked on a BeginReceive?
Basically I am using the async MSMQ API to read messages like so:
public void Start()
{
this.queue.ReceiveCompleted += this.ReceiveCompleted;
this.queue.BeginReceive();
}
void ReceiveCompleted(object sender, ReceiveCompletedEventArgs e)
{
this.queue.EndReceive(e.AsyncResult);
try
{
var m = e.Message;
m.Formatter = this.formatter;
this.Handle(m.Body);
}
finally
{
this.queue.BeginReceive();
}
}
public void Stop()
{
this.queue.ReceiveCompleted -= this.ReceiveCompleted;
//Force an EndReceive here maybe or somehow indicate that
//the BeginReceive set above should "unblock"
this.queue.Dispose();
}
Questions:
1) I'd like to signal to MSMQ in the Stop() method to unblock the current BeginReceive(). NOTE: I am aware of the BeginReceive overload that accepts a timeout. I would prefer to avoid timing out and looping periodically, this seems wasteful. Is this at all possible? If not, will Disposing the queue ensure that any registered delegates are cleaned up properly?
2) Could the repeated calls to BeginReceive in the "ReceiveCompleted" cause any leaks? i.e. is there any other cleanup required besides unsubscribing the delegate in Stop()?
this.queue.ReceiveCompleted -= this.ReceiveCompleted;
1) Yes, you just close the queue. When you do you should see a call to ReceiveCompleted with the error code 0xC0000120 which is defined to be STATUS_CANCELLED
with the text "The I/O request was canceled."
2) You have to call BeginReceive in your ReceiveCompleted event to continue receiving messages.