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
Using Named 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 Mutex
class is a bit weird/different from the normal classes in .NET.
Mutex
该类的设计与.NET 中的普通类有点奇怪/不同。
Using OpenMutex
to check for an existing Mutex
is 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 runJobWrapper
anywhere - 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 OpenExisiting
could 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()