一尘不染

是否使用Mutex防止同一程序的多个实例安全运行?

c#

我正在使用此代码来防止我的程序的第二个实例同时运行,这安全吗?

Mutex appSingleton = new System.Threading.Mutex(false, "MyAppSingleInstnceMutx");
if (appSingleton.WaitOne(0, false)) {
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new MainForm());
    appSingleton.Close();
} else {
    MessageBox.Show("Sorry, only one instance of MyApp is allowed.");
}

我担心如果发生异常并且应用程序崩溃,则Mutex仍将保留。真的吗?


阅读 267

收藏
2020-05-19

共1个答案

一尘不染

通常,这是可行的。然而,细节在于魔鬼。

首先,您要关闭一个finally块中的互斥量。否则,您的进程可能会突然终止,并使其处于信号状态,例如异常。这样可以使将来的流程实例无法启动。

但是,不幸的是,即使有一个finally块,您也必须处理一个潜在的问题,即在不释放互斥量的情况下终止进程。例如,如果用户通过TaskManager终止了进程,则可能发生这种情况。有一个在你的代码中的竞争条件,将允许第二处理,得到AbandonedMutexExceptionWaitOne通话。您将需要一个恢复策略。

我鼓励您阅读Mutex类的详细信息。使用它并不总是那么简单。


扩展种族条件的可能性:

可能发生以下事件序列,这将导致应用程序的第二个实例抛出:

  1. 正常流程启动。
  2. 第二个进程启动并获取互斥锁的句柄,但在WaitOne调用之前已被关闭。
  3. 进程#1突然终止。互斥体不会被破坏,因为进程2具有句柄。而是将其设置为放弃状态。
  4. 第二个进程再次开始运行并得到一个AbanonedMutexException
2020-05-19