使用命名互斥锁

时间:2009-05-11 08:53:01

标签: c# mutex

我有两个运行相同Windows服务的实例。他们检查彼此的健康状况并报告是否发现任何问题。我有一个需要执行的关键工作,因此我使用故障转移方法运行它,它在Master中运行,如果Master没有响应,它在slave中运行。这项工作需要通过特定的串口进行通信,我正在尝试使用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;
   }
}

3 个答案:

答案 0 :(得分:4)

我最近遇到了类似的问题。

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

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

更好的方法是使用

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

构造函数,并检查createdNew返回的值。

答案 1 :(得分:0)

您不希望在任何地方查看runJobWrapper的返回值 - 这是故意的吗?无论如何,返回值实际上意味着什么并不明显。你真的不应该抓住OpenExisiting可能抛出的每一个异常 - 内存不足吗?堆栈溢出?等等。抓住你想要正确处理的那个。

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

答案 2 :(得分:0)

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