【发布时间】:2012-03-04 23:09:11
【问题描述】:
当一个 C# 程序持有一个命名信号量时,它似乎不会在应用程序提前终止时被释放(例如通过按 Ctrl+C 或关闭控制台窗口)。至少在进程的所有实例都终止之前不会。
在这种情况下,使用命名互斥体会引发 AbandonedMutexException,但不会引发信号量。当另一个程序实例提前终止时,如何防止一个程序实例停止?
class Program
{
// Same with count > 1
private static Semaphore mySemaphore = new Semaphore(1, 1, "SemaphoreTest");
static void Main(string[] args)
{
try
{
// Blocks forever if the first process was terminated
// before it had the chance to call Release
Console.WriteLine("Getting semaphore");
mySemaphore.WaitOne();
Console.WriteLine("Acquired...");
}
catch (AbandonedMutexException)
{
// Never called!
Console.WriteLine("Acquired due to AbandonedMutexException...");
}
catch (System.Exception ex)
{
Console.WriteLine(ex);
}
Thread.Sleep(20 * 1000);
mySemaphore.Release();
Console.WriteLine("Done");
}
}
【问题讨论】:
-
信号量没有所有者。没有信号量放弃这样的事情。如果要在线程退出时自动释放,请使用互斥锁。
-
@George:查看我的更新答案,它向您展示了如何在用户关闭窗口时收到通知。
-
当您像这样进行互操作时,您永远不能忽略进程中止。很少有继续运行有意义的情况,很多隐含的状态已经消失。用 Process.Exited 事件打破僵局。