C# 当第一次运行终止时,在第二次运行中未捕获系统互斥体的放弃MutexException

C# 当第一次运行终止时,在第二次运行中未捕获系统互斥体的放弃MutexException,c#,mutex,C#,Mutex,我创建了以下测试程序: static void Main(string[] args) { using (var mutex = new Mutex(false, "foobar")) { Console.WriteLine("Created mutex"); try { try { if (!mutex.WaitOne(TimeSpan.FromSec

我创建了以下测试程序:

static void Main(string[] args)
{
    using (var mutex = new Mutex(false, "foobar"))
    {
        Console.WriteLine("Created mutex");
        try
        {
            try
            {
                if (!mutex.WaitOne(TimeSpan.FromSeconds(5), false))
                {
                    Console.WriteLine("Unable to acquire mutex");
                    Environment.Exit(0);
                }
            }
            catch (AbandonedMutexException)
            {
                Console.WriteLine("Mutex was abandoned");
            }

            Console.WriteLine("Acquired mutex - sleeping 10 seconds");
            Thread.Sleep(10000);
        }
        finally
        {
            mutex.ReleaseMutex();
            Console.WriteLine("Released mutex");
        }
    }
我的想法是运行程序,当线程休眠10秒时,我通过任务管理器终止进程。下次运行该进程时,我希望在调用
WaitOne()
时会捕获到
放弃的MutexException
。但是我没有看到输出“互斥被放弃”

报告提到以下内容:

当线程放弃互斥时,将在下一个线程中引发异常 获取互斥锁的线程

但是,当我的进程被终止时(而不是同一应用程序中的另一个线程),操作系统似乎正在释放互斥锁


有没有一种方法可以让我检测到以这种方式放弃的互斥体?

当有多个进程使用互斥体时,废弃的Mutexception很有用。如果其中一个进程被终止,另一个进程可以检测到这种情况


但是,如果互斥体仅由一个进程使用,并且该进程被终止,则该互斥体将从系统中删除(因为不再有对它的引用)。

您观察到的是正确的行为:

命名互斥体是一个系统对象,其生存期由表示它的互斥体对象的生存期限定。当第一个进程创建其互斥对象时,将创建命名互斥对象;在本例中,命名的互斥锁由运行该程序的第一个进程拥有当表示该互斥体的所有互斥体对象都已释放时,命名互斥体将被销毁

如果同时在两个单独的进程中运行程序(可能会增加超时),并终止第一个进程,则可以观察到预期的行为。当第一个进程被终止时,它放弃互斥体,这允许第二个进程获得互斥体,在这一点上它立即抛出一个废弃的MutexException


如果要确定进程是否正常退出,则需要一种不同的机制。您可以通过多种方式实现这一点,但最简单的方法之一是让流程在启动时在已知位置创建一个文件,并在优雅的清理后删除该文件。然后,您可以检查该文件,如果您找到该文件(并且没有运行的程序实例),您就知道上次关闭不正常或未成功完成。

您是对的,当您的进程死亡时,它的
互斥锁也会关闭。您是否正在尝试确定应用程序何时不正确关闭?@M.Babcock-我想我是在尝试区分获取互斥的进程正常结束或在有机会正确清理之前被终止的情况。有办法吗?我不知道。如果这不是它的工作方式,那么我只允许应用程序的单个实例的逻辑将无法正常工作,因此我很高兴它能像我预期的那样工作。:)