代码之家  ›  专栏  ›  技术社区  ›  Jim Mischel

GC。KeepAlive与使用

  •  15
  • Jim Mischel  · 技术社区  · 17 年前

    在他的 article about preventing multiple instances

    static void Main()                  // args are OK here, of course
    {
        bool ok;
        m = new System.Threading.Mutex(true, "YourNameHere", out ok);
    
        if (! ok)
        {
            MessageBox.Show("Another instance is already running.");
            return;
        }
    
        Application.Run(new Form1());   // or whatever was there
    
        GC.KeepAlive(m);                // important!
    }
    

    他解释说,GC。需要KeepAlive(m)来防止垃圾收集器提前收集互斥体,因为没有对它的额外引用。

    我的问题是:将互斥体包装在use中会做同样的事情吗?也就是说,以下情况是否也会阻止GC从我下面拔出地毯?

    static void Main()                  // args are OK here, of course
    {
        bool ok;
        using (var m = new System.Threading.Mutex(true, "YourNameHere", out ok))
        {
            if (! ok)
            {
                MessageBox.Show("Another instance is already running.");
                return;
            }
    
            Application.Run(new Form1());   // or whatever was there
        }
    }
    

    我的直觉反应是,使用会奏效,因为使用(应该)相当于:

    Mutex m = new System.Threading.Mutex(true, "YourNameHere", out ok);
    try
    {
        // do stuff here
    }
    finally
    {
        m.Close();
    }
    

    3 回复  |  直到 17 年前
        1
  •  17
  •   Jon Skeet    17 年前

    将互斥体封装在 using 声明确实会阻止它被垃圾回收,但会 Dispose ,不 Close GC.KeepAlive 当然不会)。

    如果方法的结束真的是过程的结束,我认为这不太可能对你使用的方法产生任何实际影响——我更喜欢 IDisposable .

    如果终结器不处理它,我不知道Windows本身是否会注意到进程不可能再拥有互斥体,因为它(进程)已经不存在了。我怀疑会的,但你必须查看详细的Win32文档才能确定。

        2
  •  5
  •   Guffa    17 年前

    使用 using 在这种情况下,似乎比使用更合适 GC.KeepAlive 你不仅想保留 Mutex 只要应用程序正在运行,它就会存活,您还希望它在退出主循环后立即消失。

    挂起而不处理它,可能需要一段时间才能完成,这取决于应用程序关闭时需要做多少清理工作。

        3
  •  -2
  •   Tim    17 年前