Dot-Net
程序退出時自動釋放信號量
我正在使用 Semaphore 來限制我的應用程序可以執行的並發實例的數量。
程序可以通過多種方式終止。可以
Semaphore創建它以便在程序退出時自動釋放嗎?編輯:
我想要一些魔法來自動清理退出或崩潰時擁有它的程序的信號量“提升”狀態。只是為了確保它被清除,無論如何。
更多的:
我正在尋找任何可行的選擇,考慮到:
- 如果不需要外部應用程序來控制受保護應用程序的每個實例,那就太好了
- 它不必是信號量 - 任何具有 COUNTER 並且在所有者程序死亡時自動釋放的同步對像都可以,即使它是作弊
- 我正在使用 .NET 2.0,無法在此項目上移至較新版本,但可以使用 c/c++ 和互操作來利用某些東西(如果有的話)
您可以掛鉤
AppDomain.ProcessExit事件以執行任何清理操作,例如釋放信號量。通常,命名信號量旨在協調跨程序的資源,而不考慮特定的程序生命週期。.NET 中的信號量由本機 Windows 信號量對象支持,MSDN 說:
信號量對像在其最後一個句柄關閉時被銷毀。關閉句柄不影響信號量計數;因此,請務必在關閉句柄之前或程序終止之前呼叫 ReleaseSemaphore。
因此,正確的方法是在程序終止之前進行顯式處理。
更新——要考慮的其他選項:
- 如果在事件中手動處理“緊急”釋放不可行
AppDomain.ProcessExit,請考慮創建一個IDisposable包裝器,該包裝器將在其建構子中獲取信號量並在Dispose方法中釋放它。- 另一個問題是:對於這種情況,信號量是正確的同步對象嗎?一個簡單的(命名的)互斥鎖不是更好嗎?
更新——如果應用程序崩潰或強制終止(即通過任務管理器)
ProcessExit將沒有機會得到處理。因此,在多個程序之間共享的任何非託管資源可能無法正確完成/處置/處理。有關更多詳細資訊,請參閱本文。一個可行的選擇可能是創建一個命名管道。命名管道的優點是一旦創建過程終止,它們就會停止退出。根據 MSDN:
請注意,命名管道的一個實例可能有多個與之關聯的句柄。當命名管道實例的最後一個句柄關閉時,命名管道實例總是被刪除。
有兩個選項可以限制管道實例的數量:
- 只有一個實例:通過
FILE_FLAG_FIRST_PIPE_INSTANCE在參數中指定標誌,dwOpenMode可以禁止創建多個管道實例。然後,嘗試創建管道的第二個程序將收到錯誤消息。- 更多實例:通過在
nMaxInstances參數中指定允許的實例數。當N被允許時,N+1st 程序將收到錯誤。