我有两个运行相同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;
}
}
答案 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()