当前位置:  开发笔记 > 编程语言 > 正文

GC.KeepAlive与使用

如何解决《GC.KeepAlive与使用》经验,为你挑选了2个好方法。

在他关于防止应用程序的多个实例的文章中,Michael Covington提出了以下代码:

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)是防止垃圾收集器尽早收集互斥锁所必需的,因为没有额外的引用.

我的问题:将mutex包装在一个使用中做同样的事情?也就是说,以下是否也会阻止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();
}

而且我认为m.Close()足以向JIT编译器发出信号,告知还有另一个引用,从而防止过早的垃圾收集.



1> Jon Skeet..:

在包裹互斥using声明确实会防止它被垃圾回收,但处理它(它调用Dispose,而不是Close)在结束(而GC.KeepAlive不会,很明显).

如果方法的结尾真的是这个过程的结束,我不相信它可能会产生你使用的任何实际差异 - 我更喜欢using关于处理任何实现的一般原则的陈述IDisposable.

如果在进程退出时没有处理互斥锁,我怀疑它的终结器会处理它 - 只要其他终结器不会超出终止线程超过其超时.

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


@Benny:是的 - 因为没有那个调用,对象可以被垃圾收集.对"GC.KeepAlive"的调用存在的事实意味着GC被迫将"m"视为"根"引用.
@Smashery:是的,我怀疑是这样.尽管如此,这对我来说并不是一个干净的解决方案.

2> Guffa..:

using在这种情况下使用似乎比使用更好GC.KeepAlive.Mutex只要应用程序正在运行,您不仅希望保持活动状态,还希望它在退出主循环后立即消失.

如果您只是Mutex暂停而不进行处理,可能需要一段时间才能完成,具体取决于应用程序关闭时要进行的清理工作量.

推荐阅读
和谐啄木鸟
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有