在他关于防止应用程序的多个实例的文章中,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编译器发出信号,告知还有另一个引用,从而防止过早的垃圾收集.
在包裹互斥using
声明确实会防止它被垃圾回收,但也处理它(它调用Dispose
,而不是Close
)在结束(而GC.KeepAlive
不会,很明显).
如果方法的结尾真的是这个过程的结束,我不相信它可能会产生你使用的任何实际差异 - 我更喜欢using
关于处理任何实现的一般原则的陈述IDisposable
.
如果在进程退出时没有处理互斥锁,我怀疑它的终结器会处理它 - 只要其他终结器不会超出终止线程超过其超时.
如果终结器没有处理它,我不知道Windows本身是否会注意到该进程不再可能拥有互斥锁,因为它(进程)不再存在.我怀疑它会,但你必须检查详细的Win32文档,以确定.
using
在这种情况下使用似乎比使用更好GC.KeepAlive
.Mutex
只要应用程序正在运行,您不仅希望保持活动状态,还希望它在退出主循环后立即消失.
如果您只是Mutex
暂停而不进行处理,可能需要一段时间才能完成,具体取决于应用程序关闭时要进行的清理工作量.