I do not understand where this is happening. Basically, I have a program that receives from a message queue and processes messages. A program can be stopped at any time, in which case a message loop completes what it does before the program exits. I am trying to execute this with the following code:
private MessageQueue q;
private ManualResetEventSlim idle;
public void Start()
{
idle = new ManualResetEventSlim();
q.ReceiveCompleted += this.MessageQueue_ReceiveCompleted;
q.BeginReceive();
}
public void Stop()
{
this.q.Dispose();
this.idle.Wait();
}
private void MessageQueue_ReceiveCompleted(object sender,
ReceiveCompletedEventArgs e)
{
Message inMsg;
try
{
inMsg = e.Message;
}
catch (Exception ex)
{
this.idle.Set();
return;
}
this.q.BeginReceive();
}
We hope that the Stop method eliminates the message queue and then expects the wait descriptor to be set (which should happen because the ReceiveCompleted event will be raised when it is deleted, but the e.Message property should be thrown).
However, the message loop continues! I selected the message queue, but I still manage to read it, and the exception handler is not called, which means that the idle.Wait line is waiting forever.
, , e.Message( q.EndReceive) . ? , ?
UPDATE:
(, )
class Program
{
static MessageQueue mq;
static ManualResetEventSlim idleWH;
static void Main(string[] args)
{
idleWH = new ManualResetEventSlim();
Console.WriteLine("Opening...");
using (mq = new MessageQueue(@".\private$\test"))
{
mq.Formatter = new XmlMessageFormatter(new Type[] { typeof(int) });
mq.ReceiveCompleted += mq_ReceiveCompleted;
for (int i = 0; i < 10000; ++i)
mq.Send(i);
Console.WriteLine("Begin Receive...");
mq.BeginReceive();
Console.WriteLine("Press ENTER to exit loop");
Console.ReadLine();
Console.WriteLine("Closing...");
mq.Close();
}
Console.WriteLine("Waiting...");
idleWH.Wait();
Console.WriteLine("Press ENTER (ex)");
}
static void mq_ReceiveCompleted(object sender, ReceiveCompletedEventArgs e)
{
try
{
var msg = mq.EndReceive(e.AsyncResult);
Console.Title = msg.Body.ToString();
mq.BeginReceive();
}
catch (Exception ex)
{
idleWH.Set();
return;
}
}
}