2011-04-08 104 views
3

我試圖使用信號量來控制可以同時運行多少個作業實例。雖然這對於等待方法來說非常簡單,但我還希望在運行時可以對該值進行配置,以便可以使計數增加或減少。信號量動態調整大小C#

我意識到可能會有問題撞倒倒計數,但是有沒有辦法實際做到這一點?這是使用信號量的正確方法嗎?

+0

當你說「工作實例」時,你是在談論多個進程還是單個進程? – Fantius 2011-04-08 20:13:32

回答

2

雖然這對於等待方法來說相當簡單,但我還希望可以在運行時對該值進行配置,以便可以使計數增加或減少。

我不會爲此推薦使用信號量。

如果您使用的是.NET 4,我建議的方法是創建一個自定義TaskScheduler,這將允許您在運行時更改併發級別。然後,您可以使用調用在選項中傳遞此TaskScheduler的單個調用Parallel.For/ForEach來運行整個操作,並在運行時更改併發級別。

這將使處理移動的層次變得相當容易。當級別升高時,您只需根據需要添加新線程。當它們停止時,只需從內部集合中刪除該線程(但不要停止它),並讓它完成當前的工作。這將允許您根據需要進行縮放。

+0

在當前的日子裏,我會強烈建議不要使用自定義的任務調度器,特別是在異步/等待世界中,特別是如果您使用其他第三方庫,您無法控制。當併發任務的限制被觸發時,它可以非常容易地導致死鎖。自定義任務計劃程序將在執行上下文中傳播,並且在同一流程中創建任務的任何代碼都將使用它。 – MoonStom 2016-04-07 16:59:24

2

ReleaseSemaphore文檔,對於lReleaseCount參數:

,通過該信號量對象的當前計數是要增加的金額。該值必須大於零。 如果指定的數量會導致信號量計數超過創建信號量時指定的最大計數,則計數不會更改,並且函數返回FALSE。

這和其他文檔表明,信號量不是您的限制的正確選擇。信號量一旦被創建,就有一個硬的最大值,在不重新創建信號量的情況下不能被改變。換句話說,它不是一個可以改變的動態值

您需要在此方案中找到另一種管理限制的方法。

的一種方式,你可以使用信號量將分配一個信號是對未來所有的需求足夠大,然後就抓住它足夠的「實例」來背下來減少可用的號碼你目前需要。當你想增加可用實例的數量時,只需釋放一些在開始時抓取的實例。

但是,我質疑你爲什麼要這樣做。真正決定你可以同時在這裏執行多少工作的限制因素是什麼?信號量很可能不是這個的正確答案。