3

我有两个运行相同 Windows 服务的实例。他们检查彼此的健康状况并报告是否发现任何问题。我有一项需要执行的关键工作,所以我使用故障转移方法运行它,它在主服务器中运行,如果主服务器没有响应,它在从服务器中运行。这项工作需要通过特定的串行端口进行通信,我正在尝试使用 Mutex 来检查竞争条件。我无法访问生产,所以在部署之前我想确保我的方法是好的。所以请建议我使用 Mutex 是否适合给定的情况。

if (iAmRunningInSlave)
{
   HealthClient hc = new HealthClient();
   if (!hc.CheckHealthOfMaster())
      return this.runJobWrapper(withMutex, iAmRunningInSlave);
   else
      return true; //master is ok, we dont need to run the job in slave
}
return this.runJobWrapper(withMutex, iAmRunningInSlave);

然后在 runJobWrapper

bool runJobWrapper(bool withMutex, bool iAmRunningInSlave)
{
   if (!withMutex)
      return this.runJob(iAmRunningInSlave); //the job might be interested to know 
   Mutex mutex = null;
   string mutexName = this.jobCategory + "-" + this.jobTitle; //this will be unique for given job
   try
   {
      mutex = Mutex.OpenExisting(mutexName);
      return false; //mutex is with peer, return false which will re-trigger slave
   }
   catch
   {
      try
      { //mean time mutex might have created, so wrapping in try/catch
         mutex = new Mutex(true /*initiallyOwned*/, mutexName);
         return this.runJob(iAmRunningInSlave); //the job might be interested to know where I am running
      }
      finally
      {
         if (null!=mutex) mutex.ReleaseMutex();
      }
      return false;
   }
}
4

3 回答 3

5

我最近有一个类似的问题。

该类的设计与Mutex.NET 中的普通类有点奇怪/不同。

使用OpenMutex来检查现有Mutex的并不是很好,因为您必须捕获异常。

更好的方法是使用

Mutex(bool initiallyOwned, string name, out bool createdNew) 

构造函数,并检查createdNew.

于 2009-05-11T08:57:17.747 回答
0

您不希望从runJobWrapper任何地方检查返回值 - 这是故意的吗?无论如何,返回值的实际含义并不明显。此外,您真的不应该捕获每一个OpenExisiting可能抛出的异常 - 内存不足?堆栈溢出?等等等等。只要抓住你想要正确处理的那个。

此外,您的代码看起来有些脆弱 - 如果您有竞争条件,我不会感到惊讶。

于 2009-05-11T09:00:47.913 回答
0

我注意到 mutex.ReleaseMutex() 没有立即释放互斥锁..我不得不调用 GC.Collect()

于 2009-05-13T11:22:29.893 回答