我需要为指定目录中的每个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个进程或多或少同时启动
- 当其中一个(无关紧要,哪个)结束工作时,下一个开始 - 为下一个文件
答案 0 :(得分:0)
如果我是你,我会研究排队的生产者 - 消费者模型。它的目的很准确,并且有很多很好的例子可以根据您的需要进行修改。
这是一个例子: C# producer/consumer
另一个例子: http://msdn.microsoft.com/en-us/library/hh228601%28v=vs.110%29.aspx (最后一个是4.5,但仍然是有效的IMO)
答案 1 :(得分:0)
好的,所以我尝试了this question的答案,但是 - 奇怪的是 - 我无法让它们起作用。我承认,我很匆忙,我可能犯了一些错误......
现在,我发现的最快速,最简单(也是最丑陋)的方法只是一个循环,就像下面的代码一样。它适用于仅使用给定命令行参数调用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++;
}
}