Если я получил определение сервиса, подобное этому:
[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 волшебным образом инкапсулирует мое «новое исключение (« Test »)» в MsmqPoisonMessageException, но исключение, обнаруженное в моем обработчике ошибок, всегда имеет тот же тип, что и исключение, которое я выдал.
Неужели я неправильно понимаю все поведение ядовитых сообщений? Я подумал, что если в моем коде обработки сообщений возникнет необработанное исключение, то оно окажется MsmqPoisonMessageException, потому что в противном случае у меня не было бы возможности получить идентификатор поиска для msg в очереди.
Спасибо всем.