AbandonedMutexException для системного мьютекса, не обнаруженного во 2-м запуске, когда 1-й запуск завершен - PullRequest
2 голосов
/ 01 февраля 2012

Я создал следующую тестовую программу:

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 секунд, я убиваю процесс через диспетчер задач.В следующий раз, когда я запустю процесс, я ожидаю, что AbandonedMutexException будет пойман на вызове WaitOne().Но я не вижу вывод "Mutex был заброшен".

В документации MSDN упоминается следующее:

Когдапоток отменяет мьютекс, исключение выдается в следующем потоке, который получает мьютекс.

Однако похоже, что ОС освобождает мьютекс, когда мой процесс завершается (а не другой поток внутрито же приложение).

Есть ли у меня возможность обнаружить мьютекс, оставленный таким образом?

Ответы [ 2 ]

2 голосов
/ 01 февраля 2012

То, что вы наблюдаете, является правильным поведением. Из документации :

Именованный мьютекс - это системный объект, время жизни которого ограничено временем жизни объектов Mutex, которые его представляют.Именованный мьютекс создается, когда первый процесс создает свой объект Mutex;в этом примере именованный мьютекс принадлежит первому процессу, который запускает программу. Именованный мьютекс уничтожается, когда все объекты Mutex, представляющие его, были освобождены .

Если вы запускаете вашу программу в двух отдельных процессах одновременно (возможно, увеличиваете тайм-ауты) и уничтожаетеВ первом процессе вы можете наблюдать за ожидаемым поведением.Когда первый процесс убит, он покидает Mutex, что позволяет второму процессу получить мьютекс, после чего он немедленно генерирует исключение AbandonedMutexException.

Если вы хотите определить, завершился ли ваш процесс корректно, вам нужнодругой механизм.Вы можете сделать это несколькими способами, но одним из самых простых будет процесс создания файла в известном месте во время запуска и удаления этого файла после изящной очистки.Затем вы можете проверить этот файл, и, если вы найдете файл (и не запущенный экземпляр вашей программы), вы узнаете, что последнее завершение не было корректным или не было успешно завершено.

1 голос
/ 01 февраля 2012

AbandonedMutexException полезно, когда есть несколько процессов, использующих мьютекс.Если один из процессов завершен, другой процесс может обнаружить это условие.

Однако, если мьютекс используется только одним процессом, и этот процесс завершается, мьютекс удаляется из системы (посколькубольше нет ссылок на него).

...