#.net #msmq
#.net #msmq
Вопрос:
Есть ли здесь способ подать сигнал MSMQ о разблокировке подписчиков, которые заблокированы при получении BeginReceive?
В основном я использую асинхронный MSMQ API для чтения сообщений, подобных этому:
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();
}
Вопросы:
1) Я хотел бы подать сигнал MSMQ в методе Stop(), чтобы разблокировать текущий BeginReceive(). ПРИМЕЧАНИЕ: я знаю о перегрузке BeginReceive, которая принимает тайм-аут. Я бы предпочел избегать тайм-аута и периодического цикла, это кажется расточительным. Возможно ли это вообще? Если нет, гарантирует ли удаление очереди, что все зарегистрированные делегаты будут очищены должным образом?
2) Могут ли повторные вызовы BeginReceive в «ReceiveCompleted» вызывать какие-либо утечки? т. Е. Требуется ли какая-либо другая очистка, кроме отмены подписки делегата в Stop()?
this.queue.ReceiveCompleted -= this.ReceiveCompleted;
Ответ №1:
1) Да, вы просто закрываете очередь. Когда вы это сделаете, вы должны увидеть вызов ReceiveCompleted с кодом ошибки 0xC0000120, который определен как STATUS_CANCELLED
с текстом «Запрос ввода-вывода был отменен».
2) Вы должны вызвать BeginReceive в вашем событии ReceiveCompleted, чтобы продолжить получать сообщения.