Взаимное исключение.NET на платформе окон: Что происходит с ними после того, как я буду сделан?

У меня есть простая программа.NET, которая проверяет, чтобы видеть, был ли другой экземпляр запущен:

    Mutex mutex = new Mutex(false,"MyMutexName");
    if (!mutex.WaitOne(1))
        return;

    try{
    //do stuff
    }
    catch{ //exceptions}
    finally
    {
        mutex.ReleaseMutex();
    }

Мой вопрос, что точно происходит со взаимным исключением, если Вы забываете выпускать его, когда программа заканчивается? Действительно ли это видимо в некотором компоненте панели управления окон? Где это живет?

10
задан Carlos 14 August 2010 в 17:47
поделиться

3 ответа

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

При этом автоматически уменьшится счетчик ссылок. Если счетчик дойдет до нуля (ни один процесс не имеет на нем открытого дескриптора), объект ядра будет освобожден.

Другими словами: у вас нет проблем, как бы плохо все ни обернулось. На самом деле объект-мутант находится в пуле памяти ядра. Вы можете увидеть его с помощью инструмента WinObj от SysInternals.

12
ответ дан 3 December 2019 в 20:39
поделиться

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

редактировать

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

Вызов WaitOne блокирует его и становится владельцем, а ReleaseMutex избавляется от него (при условии, что нет дополнительных вызовов WaitOne ) . Если вы завершите поток, не освободив мьютекс полностью, он оставит объект в плохом состоянии, как объясняется в тексте, который цитирует Мика.

Я воспринял ваш вопрос как о том, закрываете ли вы дескриптор до завершения процесса, что совсем другое дело.

дополнительный

На уровне SDK [API] [1] вы можете вызвать CreateMutex с ожиданием сбоя, если мьютекс с таким же именем уже был создан. В .NET (ну, по крайней мере, в 4.0) есть [конструктор] [2], который заполняет createdNew bool.

[1]: http://msdn.microsoft.com/en-us/library/ms682411 (VS.85) .aspx CreateMutex

[2]: http://msdn.microsoft. com / en-us / library / bwe34f1k (v = VS.90) .aspx Mutex

3
ответ дан 3 December 2019 в 20:39
поделиться

Из MSDN

Если поток завершается, пока владеет мьютекс, мьютекс называется заброшенный. Состояние мьютекса установлен на сигнал и следующее ожидание поток получает право собственности. Если никто не владеет мьютекс, состояние мьютекса сигнализировал. Начиная с версии 2.0 .NET Framework, AbandonedMutexException выбрасывается следующий поток, который получает мьютекс. До версии 2.0 .NET Framework, исключений не было брошен.

Внимание!

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

В случае общесистемного мьютекса заброшенный мьютекс может указывать на то, что приложение было прекращено резко (например, используя Диспетчер задач Windows).

3
ответ дан 3 December 2019 в 20:39
поделиться