下面哪个互斥锁表达式可以理想地防止.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;
}
  1. 两者之间防止多实例的理想方式是什么?

  2. 有什么区别?

  3. 此外,我看到这样的代码:

    //if not return{
    mutex.ReleaseMutex(); 
    GC.Collect(); 
    //application.Run();
    GC.KeepAlive(mutex); 
    

可以用第二种方法,但不能用第一种方法。为什么会这样呢?还是我弄错了?

基本上,这取决于对所使用的参数和方法的正确理解。如果有人能简要地详细说明,我将不胜感激,当我阅读msdn文档时,我理解不了一半。

下面哪个互斥锁表达式可以理想地防止.net应用程序的多个实例,它们的区别是什么?

在第一种情况下,您要求操作系统创建互斥锁,并在创建互斥锁时将其所有权授予您-这是通过第一个参数initiallyOwned完成的。isNew参数告诉您它是否是一个新的互斥锁。如果它是新的,那么你保证拥有它的所有权,因为这是你用initiallyOwned参数要求的。因为它是新的,你拥有它,你知道没有其他的应用程序实例在运行,因为如果有,他们已经创建了互斥锁,他们将拥有它。

第二种情况基本上是相同的事情,但以稍微不同的方式完成。它不是在创建上请求所有权,而是在WaitOne调用上请求所有权。WaitOne正在请求所有权,等待0毫秒。如果你获得了所有权,那么你就知道你的应用程序没有其他实例正在运行,原因与情况1相同。

至于用哪一种,据我所知并不重要。第一个似乎更直观,至少对我来说是这样。

添加新问题#3的答案

当应用程序完成时,它应该释放互斥锁,因为它拥有它。net可能会在应用程序退出时为你释放它,但这是一个很好的实践。GC.CollectGC.KeepAlive处理垃圾收集。我想不出为什么在处理控制启动的互斥锁时需要这些调用。我将我的互斥锁声明为静态,因此它将始终在作用域中,并且在我的应用程序的生命周期内不会被垃圾收集器释放。

为了理解这些语句中发生了什么,我们必须理解什么是互斥锁以及它们是如何操作的。我不想讲太多的细节,但我会给你指出这本参考书。阅读前几章,直到你读到关于互斥锁的部分。

在第一个代码片段中,互斥对象的声明使用isNew bool来指定当前应用程序实例是第一个运行的,也是第一个创建互斥对象的实例。这意味着应用程序的每个二次执行都可以被告知,它们对系统级互斥锁的句柄不是第一个创建和访问互斥锁的句柄。

下面的if块然后检查关联的任务是否第一个向互斥锁发出信号,然后相应地处理状态。

第二段代码完全不同。互斥锁可以在一个任务(任务B)中使用,以等待另一个任务(任务A)向互斥锁发出信号,表明任何其他任务(任务B)可以继续。

WaitOne(secs, releaseConext)方法表示,如果互斥锁被另一个线程锁定,则等待互斥锁发送X秒的信号响应。如果该方法在X秒内没有得到信号响应,它返回false,并且在示例代码的情况下,进入用于关闭应用程序的if块。

就我个人而言,我会使用第一个代码片段。我可以想象它们运行的开销是一样的。然而,在选择使用哪个版本时,作为一般实践事项,我认为第一种方法是最好的。