下面哪个互斥锁表达式可以理想地防止.net应用程序的多个实例,它们的区别是什么?
本文关键字:实例 net 应用程序 是什么 区别 表达式 理想 | 更新日期: 2023-09-27 18:06:44
我经常看到这两段代码。这两种方法对我来说都有效,但我应该坚持哪一种呢?
案例1:
bool isNew = false;
Mutex mutex = new Mutex(true, "MyApp_Mutex", out isNew);
if (!isNew)
{
MessageBox.Show("already running.", "Multiple Instances Not Allowed",
MessageBoxButtons.OK,
MessageBoxIcon.Exclamation);
return;
}
案例2:
Mutex mutex = new Mutex(false, "MyApp_Mutex"))
if (!mutex.WaitOne(0, false))
{
MessageBox.Show("already running.", "Multiple Instances Not Allowed",
MessageBoxButtons.OK,
MessageBoxIcon.Exclamation);
return;
}
两者之间防止多实例的理想方式是什么?
有什么区别?
此外,我看到这样的代码:
//if not return{ mutex.ReleaseMutex(); GC.Collect(); //application.Run(); GC.KeepAlive(mutex);
可以用第二种方法,但不能用第一种方法。为什么会这样呢?还是我弄错了?
基本上,这取决于对所使用的参数和方法的正确理解。如果有人能简要地详细说明,我将不胜感激,当我阅读msdn文档时,我理解不了一半。
在第一种情况下,您要求操作系统创建互斥锁,并在创建互斥锁时将其所有权授予您-这是通过第一个参数initiallyOwned
完成的。isNew
参数告诉您它是否是一个新的互斥锁。如果它是新的,那么你保证拥有它的所有权,因为这是你用initiallyOwned
参数要求的。因为它是新的,你拥有它,你知道没有其他的应用程序实例在运行,因为如果有,他们已经创建了互斥锁,他们将拥有它。
第二种情况基本上是相同的事情,但以稍微不同的方式完成。它不是在创建上请求所有权,而是在WaitOne
调用上请求所有权。WaitOne
正在请求所有权,等待0毫秒。如果你获得了所有权,那么你就知道你的应用程序没有其他实例正在运行,原因与情况1相同。
至于用哪一种,据我所知并不重要。第一个似乎更直观,至少对我来说是这样。
添加新问题#3的答案
当应用程序完成时,它应该释放互斥锁,因为它拥有它。net可能会在应用程序退出时为你释放它,但这是一个很好的实践。GC.Collect
和GC.KeepAlive
处理垃圾收集。我想不出为什么在处理控制启动的互斥锁时需要这些调用。我将我的互斥锁声明为静态,因此它将始终在作用域中,并且在我的应用程序的生命周期内不会被垃圾收集器释放。
为了理解这些语句中发生了什么,我们必须理解什么是互斥锁以及它们是如何操作的。我不想讲太多的细节,但我会给你指出这本参考书。阅读前几章,直到你读到关于互斥锁的部分。
在第一个代码片段中,互斥对象的声明使用isNew
bool来指定当前应用程序实例是第一个运行的,也是第一个创建互斥对象的实例。这意味着应用程序的每个二次执行都可以被告知,它们对系统级互斥锁的句柄不是第一个创建和访问互斥锁的句柄。
下面的if
块然后检查关联的任务是否第一个向互斥锁发出信号,然后相应地处理状态。
第二段代码完全不同。互斥锁可以在一个任务(任务B)中使用,以等待另一个任务(任务A)向互斥锁发出信号,表明任何其他任务(任务B)可以继续。
WaitOne(secs, releaseConext)
方法表示,如果互斥锁被另一个线程锁定,则等待互斥锁发送X
秒的信号响应。如果该方法在X
秒内没有得到信号响应,它返回false
,并且在示例代码的情况下,进入用于关闭应用程序的if
块。