使用命名互斥体

3
我有两个运行相同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个回答

5

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

Mutex 类的设计与 .NET 中的常规类有些奇怪/不同。

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

更好的方法是使用

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

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


1
有 TryOpenExisting 方法。 - Der_Meister
它出现在.NET 4.5中。 - Der_Meister

0

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


1
小心你的期望,.NET GC 不是确定性的。 - annakata
2
mutex.ReleaseMutex() 不是 Dispose()!它不会释放 Mutex 持有的资源,但它会“解锁” Mutex,以便其他进程可以通过 Mutex.WaitOne() 获取它。要处理 Mutex,请使用 mutex.Close()。请阅读文档。 - Emiswelt

0

你好像没有检查 runJobWrapper 的返回值,这是有意为之吗?实际上,返回值的含义并不明显。此外,你真的不应该捕获 OpenExisiting 可能抛出的每一个异常 - 内存不足?堆栈溢出?等等。只要捕获你想正确处理的那个异常即可。

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


抱歉,我错过了你手写的部分,请提供完整的英文文本,以便我将其翻译为中文。 - Khurram Aziz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接