为了账号安全,请及时绑定邮箱和手机立即绑定

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

/ 猿问

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

C#
慕码人8056858 2019-10-17 12:53:15

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


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仍将保留。真的吗?


查看完整描述

3 回答

?
慕的地2183247

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

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

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

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


扩展种族条件的可能性:

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

  1. 正常流程启动。

  2. 第二个进程启动并获取互斥锁的句柄,但在WaitOne调用之前已被关闭。

  3. 进程#1突然终止。互斥体不会被破坏,因为进程2具有句柄。而是将其设置为放弃状态。

  4. 第二个进程再次开始运行并得到一个AbanonedMutexException


查看完整回答
反对 回复 2019-10-17
?
红颜莎娜

为此目的,使用Windows事件更为常见和方便。例如


static EventWaitHandle s_event ;


bool created ;

s_event = new EventWaitHandle (false, 

    EventResetMode.ManualReset, "my program#startup", out created) ;

if (created) Launch () ;

else         Exit   () ;

当您的进程退出或终止时,Windows将为您关闭事件,如果没有剩余的打开句柄,则将其销毁。


添加了:用于管理会话,事件(或互斥)名称的使用Local\和Global\前缀。如果您的应用程序是按用户使用的,则只需在事件名称后附加一个经过适当修饰的登录用户名即可。


查看完整回答
反对 回复 2019-10-17
?
慕莱坞5435954

您可以使用互斥锁,但首先请确保这确实是您想要的。

因为没有明确定义“避免多个实例”。这可能意味着

  1. 不管该用户会话具有多少个桌面,都应避免在同一用户会话中启动多个实例,而应允许多个实例同时为不同的用户会话运行。

  2. 避免在同一桌面上启动多个实例,但是只要每个实例都在单独的桌面上,就允许多个实例运行。

  3. 无论存在多少个桌面或以该帐户运行的会话,都应避免为同一用户帐户启动多个实例,但要允许以不同用户帐户运行的会话同时运行多个实例。

  4. 避免在同一台计算机上启动多个实例。这意味着无论任意数量的用户使用多少个桌面,最多都可以运行该程序的一个实例。

通过使用互斥锁,基本上就是在使用定义数字4。


查看完整回答
反对 回复 2019-10-17

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信