即使没有实例 运行 也已获取 Mutex

Mutex already acquired even though no instance is running

我正在使用 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
}

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

我做错了什么?

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

要直接解决您的 'hang' 问题,您可以 specify a timeoutWaitOne 电话中。否则它将永远等待互斥锁被释放,这永远不会发生,因为它被遗弃了。

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

如果您的应用程序是 WPF,请检查 ApplicationDeployment.IsNetworkDeployed 并仅在这种情况下获取互斥量。当应用程序已从该位置发布和安装时,它将是 true,而在调试时显然是 false。

否则,请使用 #if DEBUG Preprocessor Directive 来避免 运行 互斥代码,并始终使用 "Debug" 配置调试并使用 "Release" 配置发布.确保在项目属性中检查 "Define DEBUG constant" 的调试配置。

总是在您的应用程序结束时调用 ReleaseMutex,无论它是由用户操作还是其他原因引起的。虽然我不确定如何使用控制台应用程序继续这个问题,但是 WPF 有一个很像 ASP.NET 在其 Global.asax.

中的问题

希望对您有所帮助。