使用c#Mutex类这种替代方式有什么损失吗?

时间:2017-01-17 18:45:46

标签: c# synchronization mutex interprocess

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

此代码正在制作中,我不想更改它,除非此代码存在一些大问题......是否存在?

1 个答案:

答案 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();
        }
    }
}