增加/减少 SemaphoreSlim 中可用插槽的数量
Posted
技术标签:
【中文标题】增加/减少 SemaphoreSlim 中可用插槽的数量【英文标题】:Increase/Decrease number of available slots in SemaphoreSlim 【发布时间】:2016-07-16 07:19:52 【问题描述】:编辑:我的问题,正如最初的措辞,暗示 SemaphoreSlim 创建和销毁线程是不准确的。改用“slots”代替“threads”,我相信这样更准确。
我使用SemaphoreSlim
类来控制我访问给定资源的速率,它工作得很好。但是,我正在努力如何动态增加和减少可用插槽的数量。
理想情况下,SemaphoreSlim 应具有具有以下特征的 Increase()
和 Decrease()
方法:
Increase()
将可用插槽的最大数量增加 1
Decrease()
将可用插槽的最大数量减少 1
这些方法不会等待,它们会立即返回
当达到可配置的最大槽数时,对Increase()
的后续调用相当于noop(不抛出异常)
当达到可配置的最小槽数时,后续对Decrease()
的调用相当于noop(不抛出异常)
当调用Decrease()
并且所有槽都在使用时,释放槽时最大槽数会减少
是否有 .NET 结构允许这样的事情?
【问题讨论】:
信号量不会创建或销毁线程。他们支持发布和等待。您的意思是对可以访问某个单一资源的线程数量进行运行时可配置的限制吗? 它被称为“线程池”。你不使用现有的是不明智的,但你当然可以购买替代品。在您的 Google 查询中包含“智能”或“替代”一词。 好吧,我想我没有使用正确的词汇。我并不是要暗示 SemaphoreSlim 保留了一定数量的线程(尽管我只是重新阅读了我的问题,这正是我所说的!)。我的意思是说 SemaphoreSlim 充当“看门人”,并允许限制有多少进程访问某个资源。我希望能够增加/减少“门”的数量,或者它们可能被称为“插槽”(希望这是正确的术语)。 这个对类似问题的回答听起来很有希望 (***.com/a/24067362),尽管没有人可以防止将槽数降低到确定的最小值以下。 【参考方案1】:正如评论中已经提到的,信号量既不创建也不破坏线程。您正在描述并且可能正在搜索的是 ThreadPool
类的功能。它有一些方法,如SetMinThreads
、SetMaxThreads
、QueueUserWorkItem
,并且肯定会完全按照您的意愿行事。
【讨论】:
【参考方案2】:我提出了以下扩展方法来增加槽数(达到配置的最大值):
public static void Increase(this SemaphoreSlim semaphore)
try
semaphore.Release();
catch
// An exception is thrown if we attempt to exceed the max number of concurrent tasks
// It's safe to ignore this exception
这个扩展方法可以这样使用:
var semaphore = new SemaphoreSlim(2, 5); // two slot are initially available and the max is 5 slots
semaphore.Increase(); // three slots are now available
semaphore.Increase(); // four slots are now available
semaphore.Increase(); // five slots are now available
semaphore.Increase(); // we are attempting to exceed the max; an exception is thrown but it's caught and ignored. The number of available slots remains five
现在我需要弄清楚如何实现“Decrease()”方法。有什么建议吗?
【讨论】:
以上是关于增加/减少 SemaphoreSlim 中可用插槽的数量的主要内容,如果未能解决你的问题,请参考以下文章