【发布时间】:2013-10-14 17:20:36
【问题描述】:
我有一个在 Server 2008 上运行的旧版 Windows 服务,它从事务性 MSMQ 队列中读取消息。这未配置为 WCF 服务。
我们希望通过捕获自定义异常并将相关消息发送到单独的“失败”或“中毒”队列(取决于抛出的异常类型)来改进代码(C# 4.0)中失败和中毒消息的处理。
我无法获取 Catch 代码以将消息发送到单独的队列 - 它从原始队列中消失(根据需要!),但未显示在“失败”队列中。
为了测试所有队列都不需要身份验证,并且权限设置为允许每个人做任何事情。
显然有些东西丢失或出错了,我怀疑它与交易有关,但我看不到它。或者也许这不可能像我试图做到的那样?
任何指导/建议表示赞赏!
我们简化的 PeekCompleted 事件代码:
private void MessageReceived(object sender, PeekCompletedEventArgs e)
{
using (TransactionScope txnScope = new TransactionScope())
{
MyMessageType currentMessage = null;
MessageQueue q = ((MessageQueue)sender);
try
{
Message queueMessage = q.EndPeek(e.AsyncResult);
currentMessage = (FormMessage)queueMessage.Body;
Processor distributor = new Processor();
Processor.Process(currentMessage); // this will throw if need be
q.ReceiveById(e.Message.Id);
txnScope.Complete();
q.BeginPeek();
}
catch (MyCustomException ex)
{
string qname = ".\private$\failed";
if (!MessageQueue.Exists(qname)){
MessageQueue.Create(qname , true);
}
MessageQueue fq = new MessageQueue(qname){
Formatter = new BinaryMessageFormatter()
};
System.Messaging.Message message2 = new System.Messaging.Message{
Formatter = new BinaryMessageFormatter(),
Body = currentMessage,
Label = "My Failed Message";
};
fq.Send(message2); //send to failed queue
q.ReceiveById(e.Message.Id); //off of original queue
txnScope.Complete(); // complete the trx
_queue.BeginPeek(); // next or wait
}
//other catches handle any cases where we want to tnxScope.Dispose()
编辑:2013 年 10 月 8 日
Hugh 在下面的回答让我们走上了正轨。在 Catch 块中,Failed Queue 已经创建为事务性的
MessageQueue.Create(qname , true);
但是 Send 需要一个 TransactionType 参数
fq.Send(message2,MessageQueueTransactionType.Single);
成功了。谢谢休!
【问题讨论】:
标签: c# transactions windows-services msmq