Wcf 我理解MsmqPoisonMessageException错误了吗?

Wcf 我理解MsmqPoisonMessageException错误了吗?,wcf,exception,msmq,Wcf,Exception,Msmq,如果我得到这样的服务定义: [PoisonErrorBehavior] [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple)] public class MsgQueue: IMsgQueue { public void ProcessMsg(CustomMsg msg) { throw new E

如果我得到这样的服务定义:

[PoisonErrorBehavior]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class MsgQueue: IMsgQueue
{
    public void ProcessMsg(CustomMsg msg)
    {
       throw new Exception("Test");
    }
}
(其中ProcessMsg是传入msmq消息的注册方法)

我想用我的错误处理程序处理这个异常(我把msdn中的代码作为我的模板):

公共密封类TownErrorBehavior属性:属性,IServiceBehavior
{
MsmqPoisonMessageHandler-TownErrorHandler;
公共毒物行为属性()
{
this.毒物错误处理程序=新的MsmqPoisonMessageHandler();
}
无效IServiceBehavior.Validate(ServiceDescription说明,ServiceHostBase ServiceHostBase)
{
}
void IServiceBehavior.AddBindingParameters(ServiceDescription说明、ServiceHostBase ServiceHostBase、System.Collections.ObjectModel.Collection端点、BindingParameterCollection参数)
{
}
无效IServiceBehavior.ApplyDispatchBehavior(ServiceDescription,ServiceHostBase ServiceHostBase)
{
foreach(serviceHostBase.ChannelDispatchers中的ChannelDispatcherBase ChannelDispatcherBase)
{
ChannelDispatcher ChannelDispatcher=作为ChannelDispatcher的ChannelDispatcher数据库;
channelDispatcher.ErrorHandler.Add(TownErrorHandler);
}
}
}
类MsmqPoisonMessageHandler:IErrorHandler
{
public void providefaulture(异常错误,MessageVersion版本,ref System.ServiceModel.Channels.Message错误)
{
}
公共布尔句柄错误(异常错误)
{
字符串测试=error.GetType().ToString();
//
//异常的类型永远不是MsmqPoisonMessageException!!!
//
MsmqPoisonMessageException TownException=错误为MsmqPoisonMessageException;
if(null!=异常)
{
long lookupId=TownException.MessageLookupId;
WriteLine(“中毒消息-消息查找id={0}”,lookupId);
}
}
然后我遇到了一个问题,异常永远不是MsmqPoisonMessageException类型。我本来希望.NET能神奇地将我的“新异常(“测试”)封装在MsmqPoisonMessageException中,但在我的errorhandler中捕获的异常始终与我抛出的异常类型相同

我是否误解了整个有毒消息行为?我想如果我的消息处理代码引发了一个未经处理的异常,那么该异常将变成MsmqPoisonMessageException,因为否则我将没有机会在队列中获取msg的查找id


谢谢大家。

WCF将异常封装在故障异常中


您还必须指定要在接口/协定中引发哪些异常。

首先,您需要检索事务中的消息,否则当代码引发异常时,它们将不会被放回队列。将此添加到ProcessMessage函数:

[OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
此外,您需要确保在检测到有毒消息时绑定设置为fault,并且重试次数和时间足够小,以便在测试中看到

尝试以下步骤(使用VS 2008):

  • 打开app.config文件的WCF配置工具
  • 在树中选择绑定,然后单击任务区域中的“新建绑定配置”
  • 选择端点的绑定类型(可能是netMsmqBinding或msmqIntegrationBinding)
  • 设置新绑定配置的名称
  • 将ReceiveErrorHandling属性设置为“Fault”
  • 将ReceiveRetryCount属性设置为2
  • 将RetryCycleDelay设置为“00:00:10”
  • 选择服务的端点,并将绑定配置设置为步骤4中指定的名称
  • (生产配置的ReceiveRetryCount和RetryCycleDelay可能需要不同的值。)

    [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]