我有一个使用Mutex的应用程序(我没有写这个):
static void Main(string[] args)
{
Mutex mutex = null;
try
{
mutex = Mutex.OpenExisting("SINGLEINSTANCE");
if (mutex != null)
{
return;
}
}
catch (WaitHandleCannotBeOpenedException ex)
{
mutex = new Mutex(true, "SINGLEINSTANCE");
}
// critical section here
}
但我知道正确的方法是:
private readonly Mutex m = new Mutex("SINGLEINSTANCE");
static void Main(string[] args) {
m.WaitOne();
try {
/* critical code */
}
finally {
m.ReleaseMutex();
}
}
使用此方法是因为此应用程序只能同时运行一个进程。它是一个控制台应用程序,为Web应用程序执行一些异步作业。
此代码正在制作中,我不想更改它,除非此代码存在一些大问题......是否存在?
答案 0 :(得分:2)
旧代码有一个竞争条件,其中两个进程可能会尝试同时启动,第二个进程将启动异常并在new Mutex(true, "SINGLEINSTANCE");
行崩溃。如果互斥锁已存在并且您没有竞争条件,则程序将正常退出并且永远不会执行关键部分。
您的新代码无法编译,因为您没有为Mutex
使用有效的构造函数,但是如果您已经传入false
,那么您的代码会等待先前的互斥锁被释放然后它会继续关键部分,不要提前退出该计划。
“正确”的方法是组合这两种方法并尝试创建互斥锁,并使用带有out
参数的重载来查看您是否是它的所有者。
static void Main(string[] args)
{
bool taken;
using(Mutex mutex = new Mutex(true, "SINGLEINSTANCE", out taken))
{
if(!taken)
return;
try
{
// critical section here
}
finally
{
mutex.ReleaseMutex();
}
}
}