1

我需要为指定目录中的每个 PDF 文件运行一个外部程序。

问题是——如何将外部程序进程的数量限制为用户指定的值?我在循环中运行它,如下所示:

foreach(string file in Directory.GetFiles(sourcePath))
{
    Process p = new Process();
    p.StartInfo.FileName = @"path\program.exe";
    p.StartInfo.Arguments = previouslySetArguments;
    p.Start();
}

现在的问题是,有时文件数量非常庞大,并且使用该代码,所有进程将同时运行。它确实减慢了机器速度。

另一个想法是放在p.WaitForExit();之后,p.Start();但它一次只运行一个进程,另一方面 - 减慢整个工作:)

限制进程数量以同时运行确切数量的最简单方法是什么?我想让用户决定。

假设我想一次运行最多 5 个进程。所以:
- 对于目录中的前 5 个文件,前 5 个进程或多或少同时开始
- 当其中一个(没关系,哪个)结束工作时,下一个进程开始 - 对于下一个文件

4

2 回答 2

1

如果我是你,我会研究排队的生产者消费者模型。它的目的几乎就是这样做的,并且有很多很好的示例可以修改以满足您的需求。

这是一个示例: C#生产者/消费者

另一个例子: http: //msdn.microsoft.com/en-us/library/hh228601%28v=vs.110%29.aspx (最后一个是4.5,但仍然有效的IMO)

于 2012-06-18T15:57:47.517 回答
0

好的,所以我尝试了这个问题的答案,但是 - 奇怪的是 - 我无法让它们工作。我承认,我很着急,我可能会犯一些错误......

目前,我发现的最快和最简单(也是最丑陋)的方法只是一个循环,如下面的代码。Thread.Sleep()它适用于仅使用给定命令行参数作为毫秒调用的测试程序。

现在,请解释一下,为什么它不是一个好的解决方案——我认为它不是正确的方法(不仅因为代码很难看),即使它适用于这个测试示例。

class Program
{
    // hardcoded, it's just a test:
    static int activeProcesses = 0;
    static int finishedProcesses = 0;
    static int maxProcesses = 5;
    static int runProcesses = 20;

    static string file = @"c:\tmp\dummyDelay.exe";

    static void Main(string[] args)
    {
        Random rnd = new Random();

        while (activeProcesses + finishedProcesses < runProcesses)
        {
            if (activeProcesses < maxProcesses)
            {
                Process p = new Process();
                p.EnableRaisingEvents = true;
                p.Exited += new EventHandler(pExited);
                p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                p.StartInfo.FileName = file;
                p.StartInfo.Arguments = rnd.Next(2000, 5000).ToString();
                p.Start();
                Console.WriteLine("Started: {0}", p.Id.ToString());
                activeProcesses++;
            }
        }

    }

    static void pExited(object sender, EventArgs e)
    {
        Console.WriteLine("Finished: {0}", ((Process)sender).Id.ToString());
        ((Process)sender).Dispose();
        activeProcesses--;
        finishedProcesses++;
    }
}
于 2012-06-25T10:00:54.963 回答