【发布时间】:2018-01-10 05:54:38
【问题描述】:
我有一个从 Microsoft 消息队列 (netMsmqBinding) 接收消息的 WCF 服务。
如果消息队列不可用,我希望我的服务能够恢复。我的代码应该无法打开服务,但稍后再试。
我有代码可以在队列不可用时识别错误:
static bool ExceptionIsBecauseMsmqNotStarted(TypeInitializationException ex)
{
MsmqException msmqException = ex.InnerException as MsmqException;
return ((msmqException != null) && msmqException.HResult == (unchecked((int)(0xc00e000b))));
}
所以这应该很简单:我调用ServiceHost.Open(),捕获这个异常,等待一两秒,然后重复直到我的Open调用成功。
问题是,如果这个异常被抛出一次,它会继续被抛出。消息队列可能已经可用,但我正在运行的进程处于错误状态,我会继续获取TypeInitializationException,直到我关闭我的进程并重新启动它。
有没有办法解决这个问题?我可以让 WCF 原谅队列并真正尝试再听一遍吗?
这是我的服务开启代码:
public async void Start()
{
try
{
_log.Debug("Starting the data warehouse service");
while(!_cancellationTokenSource.IsCancellationRequested)
{
try
{
_serviceHost = new ServiceHost(_dataWarehouseWriter);
_serviceHost.Open();
return;
}
catch (TypeInitializationException ex)
{
_serviceHost.Abort();
if(!ExceptionIsBecauseMsmqNotStarted(ex))
{
throw;
}
}
await Task.Delay(1000, _cancellationTokenSource.Token);
}
}
catch (Exception ex)
{
_log.Error("Failed to start the service host", ex);
}
}
这里是堆栈信息。第一次抛出内部异常的堆栈跟踪是:
以及外部异常堆栈的顶部条目:
System.ServiceModel.Channels.MsmqChannelListenerBase`1.get_TransportManagerTable()
System.ServiceModel.Channels.TransportManagerContainer..ctor(TransportChannelListener listener)
【问题讨论】:
-
所以您的意思是即使您捕获了异常,但仍然存在关联的不良状态?
-
@N-ate:这是我对正在发生的事情的猜测。 (即使我捕捉到异常,中止服务主机并创建一个新的服务主机)
-
不知道是不是跟executionContext或者synchronizationContext有关。
标签: wcf msmq netmsmqbinding msmq-wcf