C# 使用命名互斥

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/847255/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 03:58:51  来源:igfitidea点击:

Using Named Mutex

c#mutex

提问by Khurram Aziz

I have two instances running of same Windows Service. They check the health of each other and report if any issue is found. I have a critical job that needs to be performed so I am running it with a fail-over approach, it runs in Master, and if Master is not responding it runs in slave. This job needs to communicate over a specific serial port, I am trying to use Mutex to check for race condition. I dont have access to production, so before deploying I want to make sure my approach is fine. So please suggest if my use of Mutex is fine for the given case.

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

And then in runJobWrapper

然后在 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;
   }
}

采纳答案by leppie

I had a similar issue recently.

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

The design of the Mutexclass is a bit weird/different from the normal classes in .NET.

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

Using OpenMutexto check for an existing Mutexis not really nice as you have to catch an exception.

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

A better approach is to use the

更好的方法是使用

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

constructor, and check the value returned by createdNew.

构造函数,并检查createdNew.

回答by 1800 INFORMATION

You don't look to check the return value from runJobWrapperanywhere - is this intentional? It is not obvious what the return value actually means anyway. Also you really shouldn't catch each any every exception that OpenExisitingcould possibly throw - Out of memory? Stack overflow? etc. etc. Just catch the one you mean to handle correctly.

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

Also your code looks to be somewhat fragile - I wouldn't be surprised if you have race conditions.

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

回答by Khurram Aziz

I noticed that mutex.ReleaseMutex() was not releasing the mutex immediately..I had to call GC.Collect()

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