C# 下面哪一个互斥表达式理想地阻止了.Net应用程序的多个实例?有什么区别?

C# 下面哪一个互斥表达式理想地阻止了.Net应用程序的多个实例?有什么区别?,c#,winforms,c#-2.0,mutex,multiple-instances,C#,Winforms,C# 2.0,Mutex,Multiple Instances,通常我会在周围看到这两段代码。这两种方法在我的情况下都有效,但我应该坚持哪一种 案例1: bool isNew = false; Mutex mutex = new Mutex(true, "MyApp_Mutex", out isNew); if (!isNew) { MessageBox.Show("already running.", "Multiple Instances Not Allowed",

通常我会在周围看到这两段代码。这两种方法在我的情况下都有效,但我应该坚持哪一种

案例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
    参数所要求的。因为它是新的,并且是您自己的,所以您知道没有其他正在运行的应用程序实例,因为如果有的话,他们可能已经创建了互斥对象,并且拥有它

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

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

    为新问题添加答案#3


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

    为了了解这些语句中发生了什么,必须了解互斥体是什么以及它们如何操作。我不会详细说明,但我会告诉你这一点。阅读前几章,直到到达关于互斥体的部分

    第一段代码中的互斥体声明使用
    isNew
    bool指定当前应用程序实例是第一个运行的实例,以及第一个创建互斥体的实例。这意味着可以通知应用程序的每个次执行,它们对系统范围互斥体的句柄不是第一个创建和访问互斥体的句柄

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

    第二段代码完全不同。可以在任务(任务B)中使用互斥体来等待另一个任务(任务A)通知互斥体任何其他任务(任务B)都可以继续

    WaitOne(secs,releaseConext)
    方法说,如果互斥锁被另一个线程锁定,等待它发送信号响应
    X
    秒。如果该方法在
    X
    秒内未获得信号响应,则返回
    false
    ,对于示例代码,则输入用于关闭应用程序的
    If


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

    我还有一个疑问,我将向问题补充,对不起,在C.C.G回应之前,我没有回答您更新的、附加的问题(3)。他已经把这个反应一针见血了。是的,额外的代码被认为是“好的实践”,但是GC在过去10年中得到了很好的优化,我从来没有发现需要这样的代码+1到CCG。对我来说这听起来也很合乎逻辑,但是,为什么没有人在第一种方法中提到GC和所有这些呢?这取决于代码有多旧。特别是如果你正在寻找文章,那些参考文章,那些参考文章。。。这可以追溯到.NET1.1时代。这种类型的代码在当时更为重要。我还将使用一个名为mutex的全局代码,这样您的单实例逻辑将在终端服务服务器环境中工作。我还有一个疑问,我将补充这个问题。如果你能调查一下的话,会有很大帮助的。