有没有办法可以在信号量中等待多个Release()?
说我有这样的事情:
class GoRunners {
Semaphore runnersSemaphore;
List<Result> results = new List<Result>();
private void RunForestRun(object aRunner) {
runnersSemaphore.Wait();
Runner runner = (Runner)aRunner;
results.Add(runner.Run());
runnersSemaphore.Release();
}
private List<Result> Go() {
List<Runners>() runners = CreateSomeRunners();
runnersSemaphore = new Semaphore(2, 2); // At most two threads at once
runners.ForEach((runner) => new Thread(RunForestRun).Start(runner); )}
runnersSemaphore.WaitFor(runners.Count); //How do I do this?
return results;
}
}
我知道我可以在循环中使用多个WaitOne()
,但这看起来不太好。但如果没有别的办法,我对它很好。如果有另一种机制可以达到我想要的效果(我曾经在使用信号量的Java中做过这样的事情,所以我的思想朝这个方向发展)。
注意:我已经锁定在.NET 3.5中:(
答案 0 :(得分:3)
您需要在foreach循环中移动速率限制代码,这样在所有运行程序启动之后循环才会退出。完成后,您只需等待剩余的两个跑步者完成,然后再返回结果。
class GoRunners {
Semaphore runnersSemaphore;
List<Result> results = new List<Result>();
private void RunForestRun(object aRunner) {
try {
Runner runner = (Runner)aRunner;
var result = runner.Run();
lock(results)
{
results.Add(result)//List is not thread safe, you need to lock on it or use a different threadsafe collection (I don't know if there are any in .NET 3.5)
}
}
finally { //A little safety in case a execption gets thrown inside "runner.Run()"
runnersSemaphore.Release();
}
}
const int MAX_RUNNERS = 2; //I hate magic numbers in code if they get spread across more than one line, move the max out to a const variable.
private List<Result> Go() {
List<Runners>() runners = CreateSomeRunners();
runnersSemaphore = new Semaphore(MAX_RUNNERS, MAX_RUNNERS); // At most two threads at once
foreach(var runner in runners)
{
runnersSemaphore.WaitOne(); //This goes in here now. New threads will not be started unless there is less than 2 runners running.
new Thread(RunForestRun).Start(runner);
}
for(int i = 0; i < MAX_RUNNERS; i++) {
runnersSemaphore.WaitOne(); //Wait for the currently running runners to finish.
}
return results;
}
}