2011-04-08 115 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。

这和其他文档表明,信号量不是您的限制的正确选择。信号量一旦被创建,就有一个硬的最大值,在不重新创建信号量的情况下不能被改变。换句话说,它不是一个可以改变的动态值

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

的一种方式,你可以使用信号量将分配一个信号是对未来所有的需求足够大,然后就抓住它足够的“实例”来背下来减少可用的号码你目前需要。当你想增加可用实例的数量时,只需释放一些在开始时抓取的实例。

但是,我质疑你为什么要这样做。真正决定你可以同时在这里执行多少工作的限制因素是什么?信号量很可能不是这个的正确答案。