【问题标题】:Did i understood MsmqPoisonMessageException wrong?我理解 MsmqPoisonMessageException 错误吗?
【发布时间】:2009-06-19 10:10:03
【问题描述】:

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

[PoisonErrorBehavior]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class MsgQueue: IMsgQueue
{
    public void ProcessMsg(CustomMsg msg)
    {
       throw new Exception("Test");
    }
}

(其中 ProcessMsg 是传入 msmq-messages 的注册方法)

我想用我的错误处理程序处理异常(我从 msdn 获取代码作为我的模板):

public sealed class PoisonErrorBehaviorAttribute : Attribute, IServiceBehavior
    {
        MsmqPoisonMessageHandler poisonErrorHandler;

        public PoisonErrorBehaviorAttribute()
        {
            this.poisonErrorHandler = new MsmqPoisonMessageHandler();
        }

        void IServiceBehavior.Validate(ServiceDescription description, ServiceHostBase serviceHostBase)
        {
        }

        void IServiceBehavior.AddBindingParameters(ServiceDescription description, ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, BindingParameterCollection parameters)
        {
        }

        void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription description, ServiceHostBase serviceHostBase)
        {
            foreach (ChannelDispatcherBase channelDispatcherBase in serviceHostBase.ChannelDispatchers)
            {
                ChannelDispatcher channelDispatcher = channelDispatcherBase as ChannelDispatcher;
                channelDispatcher.ErrorHandlers.Add(poisonErrorHandler);
            }
        }
    }

    class MsmqPoisonMessageHandler : IErrorHandler
    {
        public void ProvideFault(Exception error, MessageVersion version, ref System.ServiceModel.Channels.Message fault)
        {
        }

        public bool HandleError(Exception error)
        {
            string test = error.GetType().ToString();
            //
            // The type of the exception is never MsmqPoisonMessageException !!!
            //
            MsmqPoisonMessageException poisonException = error as MsmqPoisonMessageException;
            if (null != poisonException)
            {
                long lookupId = poisonException.MessageLookupId;
                Console.WriteLine(" Poisoned message -message look up id = {0}", lookupId);
            }
       }

然后我遇到的问题是异常永远不是 MsmqPoisonMessageException 类型。我原以为 .NET 会神奇地将我的“new Exception("Test")”封装在 MsmqPoisonMessageException 中,但在我的错误处理程序中捕获的异常始终与我抛出的异常类型相同。

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

谢谢大家。

【问题讨论】:

    标签: wcf exception msmq


    【解决方案1】:

    WCF 将异常封装在一个错误异常中。

    http://msdn.microsoft.com/en-us/library/system.servicemodel.faultexception.aspx

    您还必须指定要在接口/合同中抛出哪些异常。

    【讨论】:

      【解决方案2】:

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

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

      此外,您需要确保在检测到有害消息时将绑定设置为错误,并且重试计数和时间足够小,以便您在测试中看到它。

      尝试这些步骤(使用 VS 2008):

      1. 为您的 app.config 文件打开 WCF 配置工具
      2. 在树中选择绑定,然后在任务区点击“新建绑定配置”
      3. 选择端点的绑定类型(可能是 netMsmqBinding 或 msmqIntegrationBinding)
      4. 设置新绑定配置的名称
      5. 将 ReceiveErrorHandling 属性设置为“故障”
      6. 将 ReceiveRetryCount 属性设置为 2
      7. 将 RetryCycleDelay 设置为“00:00:10”
      8. 选择服务的端点并将绑定配置设置为您在第 4 步中指定的名称。

      (对于生产配置,您可能需要不同的 ReceiveRetryCount 和 RetryCycleDelay 值。)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-05
        • 2020-08-22
        • 1970-01-01
        • 1970-01-01
        • 2018-05-21
        • 2021-03-08
        相关资源
        最近更新 更多