Если я получил такое определение службы:
[PoisonErrorBehavior]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class MsgQueue: IMsgQueue
{
public void ProcessMsg(CustomMsg msg)
{
throw new Exception("Test");
}
}
(где ProcessMsg — зарегистрированный метод для входящих msmq-сообщений)
и я хочу обработать исключение с помощью моего обработчика ошибок (я взял код из 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 волшебным образом инкапсулирует мое «новое исключение («Тест»)» в MsmqPoisonMessageException, но исключение, перехваченное в моем обработчике ошибок, всегда имеет тот же тип, что и исключение, которое я выдал.
Я неправильно понимаю все это поведение ядовитых сообщений? Я думал, что если мой код обработки сообщений выдаст необработанное исключение, тогда это исключение окажется MsmqPoisonMessageException, потому что в противном случае у меня не было бы шанса получить идентификатор поиска msg в очереди.
Спасибо вам всем.