我正在使用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中的“停止”按钮进行调试时终止程序,我通常无法重新启动我的应用程序,除非我断开了我的用户并重新登录。今天早上它甚至在重启后发生了!
我做错了什么?
答案 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的功能。
我希望这会有所帮助。