Вы можете подключиться к событию AppDomain.ProcessExit
для выполнения любых операций очистки, таких как освобождение семафора.
Как правило, именованные семафоры предназначены для координации ресурсов между процессами без учета конкретного времени жизни процесса. Семафоры в .NET поддерживаются собственными объектами семафора Windows , а MSDN говорит:
Объект семафора уничтожается, когда его последний дескриптор был закрыт. Закрытие дескриптора не влияет на количество семафоров; поэтому обязательно вызовите ReleaseSemaphore перед закрытием дескриптора или перед завершением процесса.
Следовательно, правильный подход - явная обработка перед завершением процесса.
Обновление - Другие варианты для рассмотрения:
- В случае, если не представляется возможным обработать «аварийное» освобождение вручную в событии
AppDomain.ProcessExit
, рассмотрите возможность создания оболочки IDisposable
, которая получит семафор в своем конструкторе и освободит его методом Dispose
.
- Другой вопрос: является ли семафор подходящим объектом синхронизации для этого случая? Разве простой (именованный) мьютекс не будет работать лучше?
Обновление - В случае сбоя приложения или принудительного завершения (т. Е. Через диспетчер задач) ProcessExit
не будет иметь шансов быть обработанным. Следовательно, любые неуправляемые ресурсы, совместно используемые несколькими процессами, могут быть неправильно завершены / удалены / обработаны. Подробнее см. в этой статье .
Возможным вариантом может быть , создающий именованный канал . Преимущество именованных каналов в том, что они перестают выходить после завершения процесса создания. По данным MSDN:
Обратите внимание, что экземпляр именованного канала может иметь более одного дескриптора, связанного с ним. Экземпляр именованного канала всегда удаляется, когда закрывается последний дескриптор экземпляра именованного канала.
Существует два варианта ограничения количества экземпляров канала:
- Всего один экземпляр: указав флаг
FILE_FLAG_FIRST_PIPE_INSTANCE
в аргументе dwOpenMode
, можно запретить создание нескольких экземпляров канала. Затем второй процесс, пытающийся создать канал, получит ошибку.
- Больше экземпляров: указав количество разрешенных экземпляров в аргументе
nMaxInstances
. Если разрешено N
, процесс N+1
будет получать ошибку.