即使没有实例运行,Mutex也已经获得了

时间:2018-03-28 07:50:38

标签: c# .net mutex

我正在使用Mutex对象来阻止应用程序的多个实例同时运行。

这是相关代码:

// class attribute
private static Mutex applicationMutex = new Mutex(true, "MyProgram"); 

// Main()
try
{
    if (!applicationMutex.WaitOne(TimeSpan.Zero, true))
    {
        MessageBox.Show("Already running.");
        Application.Current.Shutdown();
    }
}
catch (AbandonedMutexException)
{
    // pass
}

它似乎工作正常,但我注意到有时它似乎“挂起”:例如,如果我在使用Visual Studio中的“停止”按钮进行调试时终止程序,我通常无法重新启动我的应用程序,除非我断开了我的用户并重新登录。今天早上它甚至在重启后发生了!

我做错了什么?

1 个答案:

答案 0 :(得分:2)

在调试期间创建命名的Mutex对象时,代码不太可能在获取的互斥锁上调用ReleaseMutex() - 尤其是当您从VS停止调试会话时。

要直接解决“挂起”问题,您可以WaitOne来电specify a timeout。否则它将永远等待释放互斥锁,这将永远不会发生,因为它被放弃了。

虽然我没有时间为它编写测试,但似乎可能会再次获得一个废弃的互斥锁,请参阅Mutex.OpenExisting。在查看应用程序是否正在生产之后,这对我们来说不是问题:

如果您的应用是WPF,请检查ApplicationDeployment.IsNetworkDeployed是否只获取该情况下的互斥锁。当应用程序从该位置发布并安装时,它将是true,而在调试时显然是错误的。

否则,使用#if DEBUG Preprocessor Directive来避免运行互斥代码,并始终使用“调试”配置进行调试,并使用“发布”配置进行调试。确保在项目属性中检查调试配置的“定义DEBUG常量”。

当您的应用程序结束时,始终调用ReleaseMutex,无论是通过用户操作还是其他操作。我不知道如何使用控制台应用程序继续这样做,但是WPF在其Global.asax中有一个类似于ASP.NET的功能。

我希望这会有所帮助。

相关问题