这种使用 c# Mutex class 的替代方式是否有任何损失?

Are there any loss in this alternative way of using c# Mutex class?

我有一个使用 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 应用程序执行一些异步作业。

这段代码正在制作中,我不想更改它,除非这段代码有什么大问题...有吗?

旧代码有一个竞争条件,两个进程可能会尝试同时启动,第二个启动的进程将抛出异常并在 new Mutex(true, "SINGLEINSTANCE"); 行崩溃。如果互斥量已经存在并且您没有竞争条件,程序将正常退出并且永远不会执行临界区。

您的新代码无法编译,因为您没有为 Mutex 使用有效的构造函数,但是如果您传入了 false,您的代码将等待之前的互斥体被释放它将继续执行关键部分,永远不会提前退出程序。

"Correct" 方法是结合这两种方法并尝试创建互斥锁,然后使用带有 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();
        }
    }
}