C# “我该怎么做?”;“等待不止一个”;在信号灯里?

C# “我该怎么做?”;“等待不止一个”;在信号灯里?,c#,multithreading,semaphore,C#,Multithreading,Semaphore,有没有一种方法可以在一个信号量中等待多个Release() 假设我有这样的东西: class GoRunners { Semaphore runnersSemaphore; List<Result> results = new List<Result>(); private void RunForestRun(object aRunner) { runnersSemaphore.Wait(); Runner r

有没有一种方法可以在一个信号量中等待多个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;
    }
}
类gorunner{
信号灯runnersSemaphore;
列表结果=新列表();
私有void RunForestRun(对象aRunner){
runnersesemaphore.Wait();
Runner=(Runner)aRunner;
results.Add(runner.Run());
runnersesemaphore.Release();
}
私人名单Go(){
List()runners=CreateSomeRunners();
runnersSemaphore=新信号量(2,2);//一次最多两个线程
runners.ForEach((runner)=>新线程(RunForestRun.Start(runner);)}
runnersemaphore.WaitFor(runners.Count);//我该怎么做?
返回结果;
}
}
我知道我可以在循环中使用多个
WaitOne()
s,但这看起来不太好。但是如果没有别的办法,我也同意。如果有另一种机制可以实现我想要的,那也没关系(我以前在Java中使用信号量做类似的事情,所以我的想法是朝这个方向走的)


注意:我被锁定在.NET 3.5中:(

您需要将您的速率限制代码移动到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;
    }
}
类gorunner{
信号灯runnersSemaphore;
列表结果=新列表();
私有void RunForestRun(对象aRunner){
试一试{
Runner=(Runner)aRunner;
var result=runner.Run();
锁定(结果)
{
results.Add(result)//列表不是线程安全的,您需要锁定它或使用其他线程安全集合(我不知道.NET3.5中是否有)
}
}
最后{//在“runner.Run()”中抛出一个execption时有一点安全性
runnersesemaphore.Release();
}
}
const int MAX_RUNNERS=2;//我讨厌代码中的幻数如果它们分布在多行上,请将MAX移出到一个const变量。
私人名单Go(){
List()runners=CreateSomeRunners();
runnersSemaphore=新信号量(MAX_RUNNERS,MAX_RUNNERS);//一次最多两个线程
foreach(变量runner in runner)
{
runnersSemaphore.WaitOne();//现在进入这里。除非运行的运行程序少于2个,否则不会启动新线程。
新线程(RunForestRun).Start(runner);
}
对于(int i=0;i
您需要将您的速率限制代码移动到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;
    }
}
类gorunner{
信号灯runnersSemaphore;
列表结果=新列表();
私有void RunForestRun(对象aRunner){
试一试{
Runner=(Runner)aRunner;
var result=runner.Run();
锁定(结果)
{
results.Add(result)//列表不是线程安全的,您需要锁定它或使用其他线程安全集合(我不知道.NET3.5中是否有)
}
}
最后{//在“runner.Run()”中抛出一个execption时有一点安全性
runnersesemaphore.Release();
}
}
const int MAX_RUNNERS=2;//我讨厌代码中的幻数如果它们分布在多行上,请将MAX移出到一个const变量。
私人名单Go(){
List()runners=CreateSomeRunners();
runnersSemaphore=新信号量(MAX_RUNNERS,MAX_RUNNERS);//一次最多两个线程
foreach(变量runner in runner)
{
runnersSemaphore.WaitOne();//现在进入这里。除非运行的运行程序少于2个,否则不会启动新线程。
新线程(RunForestRun).Start(runner);
}
对于(int i=0;i
您需要将您的速率限制代码移动到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;
    }
}
类gorunner{
信号灯runnersSemaphore;
列表结果=新列表();
私有void RunForestRun(对象aRunner){
试一试{
Runner=(Runner)aRunner;
var result=runner.Run();
锁定(结果)
{
results.Add(result)//列表不是线程安全的,您需要锁定它或使用其他线程安全集合(我不知道.NET3.5中是否有)
}
}
最后{//在“runner.Run()”中抛出一个execption时有一点安全性
runnersesemaphore.Release();
}
}
const int MAX_RUNNERS=2;//我讨厌代码中的幻数如果它们分布在多行上,请将MAX移出到一个const变量。
私人名单Go(){
List()runners=CreateSomeRunners();
runnersSemaphore=新信号量(MAX_RUNNERS,MAX_RUNNERS);//一次最多两个线程
foreach(变量runner in runner)
{
runnersSemaphore.WaitOne();//现在进入这里。除非运行的运行程序少于2个,否则不会启动新线程。
新线程(RunForestRun).Start(runner);
}
对于(int i=0;i