Dot-Net

程序退出時自動釋放信號量

  • July 26, 2012

我正在使用 Semaphore 來限制我的應用程序可以執行的並發實例的數量。

程序可以通過多種方式終止。可以Semaphore創建它以便在程序退出時自動釋放嗎?

編輯:

我想要一些魔法來自動清理退出或崩潰時擁有它的程序的信號量“提升”狀態。只是為了確保它被清除,無論如何。

更多的:

我正在尋找任何可行的選擇,考慮到:

  • 如果不需要外部應用程序來控制受保護應用程序的每個實例,那就太好了
  • 它不必是信號量 - 任何具有 COUNTER 並且在所有者程序死亡時自動釋放的同步對像都可以,即使它是作弊
  • 我正在使用 .NET 2.0,無法在此項目上移至較新版本,但可以使用 c/c++ 和互操作來利用某些東西(如果有的話)

您可以掛鉤AppDomain.ProcessExit事件以執行任何清理操作,例如釋放信號量。

通常,命名信號量旨在協調跨程序的資源,而不考慮特定的程序生命週期。.NET 中的信號量由本機 Windows 信號量對象支持,MSDN 說:

信號量對像在其最後一個句柄關閉時被銷毀。關閉句柄不影響信號量計數;因此,請務必在關閉句柄之前或程序終止之前呼叫 ReleaseSemaphore。

因此,正確的方法是在程序終止之前進行顯式處理。


更新——要考慮的其他選項:

  1. 如果在事件中手動處理“緊急”釋放不可行AppDomain.ProcessExit,請考慮創建一個IDisposable包裝器,該包裝器將在其建構子中獲取信號量並在Dispose方法中釋放它。
  2. 另一個問題是:對於這種情況,信號量是正確的同步對象嗎?一個簡單的(命名的)互斥鎖不是更好嗎?

更新——如果應用程序崩潰或強制終止(即通過任務管理器)ProcessExit將沒有機會得到處理。因此,在多個程序之間共享的任何非託管資源可能無法正確完成/處置/處理。有關更多詳細資訊,請參閱本文

一個可行的選擇可能是創建一個命名管道。命名管道的優點是一旦創建過程終止,它們就會停止退出。根據 MSDN:

請注意,命名管道的一個實例可能有多個與之關聯的句柄。當命名管道實例的最後一個句柄關閉時,命名管道實例總是被刪除。

有兩個選項可以限制管道實例的數量:

  1. 只有一個實例:通過FILE_FLAG_FIRST_PIPE_INSTANCE在參數中指定標誌,dwOpenMode可以禁止創建多個管道實例。然後,嘗試創建管道的第二個程序將收到錯誤消息。
  2. 更多實例:通過在nMaxInstances參數中指定允許的實例數。當N被允許時,N+1st 程序將收到錯誤。

引用自:https://stackoverflow.com/questions/5231569