C# 如何处理windows服务中的消息队列故障?

C# 如何处理windows服务中的消息队列故障?,c#,windows-services,msmq,C#,Windows Services,Msmq,我有一个windows服务,它通常从另一台服务器的msmq接收消息 它大部分时间都能工作,但每个月会抛出以下错误: 队列不存在,或者您没有足够的权限执行该操作 Exception Message: The queue does not exist or you do not have sufficient permissions to perform the operation. Stack Trace: at System.Messaging.MessageQueue.ResolveF

我有一个windows服务,它通常从另一台服务器的msmq接收消息

它大部分时间都能工作,但每个月会抛出以下错误:

队列不存在,或者您没有足够的权限执行该操作

Exception Message: The queue does not exist or you do not have sufficient permissions to perform the operation.
 Stack Trace:    at System.Messaging.MessageQueue.ResolveFormatNameFromQueuePath(String queuePath, Boolean throwException)
   at System.Messaging.MessageQueue.get_FormatName()
或者有时:

Exception Message: 
 Stack Trace:    at System.Messaging.MessageQueue.MQCacheableInfo.get_ReadHandle()
   at System.Messaging.MessageQueue.StaleSafeReceiveMessage(UInt32 timeout, Int32 action, MQPROPS properties, NativeOverlapped* overlapped, ReceiveCallback receiveCallback, CursorHandle cursorHandle, IntPtr transaction)
所以这是随机的,唯一的解决办法是手动重启服务

对于消息队列异常,我们抛出异常,这就是为什么运行应用程序的唯一解决方案是手动重新启动服务

我想让应用程序重试5次,然后在连续失败的情况下重新启动

我已经尝试了下面的代码,但当它停止时,它显然不会返回到下面的代码来再次启动它,因为服务本身正在尝试重新启动

catch (MessageQueueException e)
                        {
                            if (e.MessageQueueErrorCode != MessageQueueErrorCode.IOTimeout)
                            {
                                // Very unusual
                                LogWrapper.WriteErrorLog(e, "MessageQueueException occuring for the following machine: " + queue.MachineName + " and the following queue: " + queue.QueueName, false, DateTime.Now);

                                // Restart service if it fails for more than 5 times
                                if (maxTries == 0)
                                {
                                    var service = new System.ServiceProcess.ServiceController(serviceName);
                                    service.Stop();
                                    //service.WaitForStatus(ServiceControllerStatus.Stopped);

                                    LogWrapper.WriteErrorLog(e, "Restarting service as it reached maximum retry count for exception: " + e.Message, false, DateTime.Now);
                                    service.Start();
                                    service.WaitForStatus(ServiceControllerStatus.Running);
                                    //Environment.Exit(1);
                                }

                                maxTries--;
                                //throw;
                            }

在这种情况下,最好的解决方案是什么?

您是否控制服务的安装方式?如果您将当前进程设置为在出现故障时重新启动服务(例如),那么您可以使其崩溃,并让windows为您重新启动服务。MQ应该能够处理类似这样的故障。但是,当队列位于另一台机器上,而该机器或网络变得不稳定时,就不能这样做。考虑使用一个专用队列。@ SalekkWin:你的意思是这样吗?这也是一个很好的实践吗?好的@HansPassant,你指的是远程机器中的私有队列,对吗?那么,私有队列将如何避免这种情况呢?如果您无法更改它,请不要将其视为您的问题。片状生产机器或网络不是程序员的问题,而是IT员工的工作。任何有权对此采取行动的人都可以很容易地解决它。包括@slawekin提到的配置更改。只要确保你的程序在发生故障时崩溃并烧掉就行了。你能控制服务的安装方式吗?如果您将当前进程设置为在出现故障时重新启动服务(例如),那么您可以使其崩溃,并让windows为您重新启动服务。MQ应该能够处理类似这样的故障。但是,当队列位于另一台机器上,而该机器或网络变得不稳定时,就不能这样做。考虑使用一个专用队列。@ SalekkWin:你的意思是这样吗?这也是一个很好的实践吗?好的@HansPassant,你指的是远程机器中的私有队列,对吗?那么,私有队列将如何避免这种情况呢?如果您无法更改它,请不要将其视为您的问题。片状生产机器或网络不是程序员的问题,而是IT员工的工作。任何有权对此采取行动的人都可以很容易地解决它。包括@slawekin提到的配置更改。只要确保你的程序在它发生时崩溃并烧毁。