我正在处理一个带有文件名的队列。每个文件都必须由外部二进制文件处理。这工作正常,但它一次只处理一个文件。是否有可能两个并行产生多个进程?
Queue<string> queue = new Queue<string>();
queue.Enqueue("1.mp3");
queue.Enqueue("2.mp3");
queue.Enqueue("3.mp3");
...
queue.Enqueue("10000.mp3");
while (queue.Count > 0)
{
string file = queue.Dequeue();
Process p = new Process();
p.StartInfo.FileName = @"binary.exe";
p.StartInfo.Arguments = file;
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardOutput = true;
p.Start();
p.WaitForExit();
}
更新:我喜欢 Alex LE 的解决方案(生成进程,但一次只有 5 个),但是是否可以按照 Ben Voigt 的建议等待子进程退出?
编辑 1:我需要检查 p.ExitCode == 0 以进行一些数据库更新。
最佳答案
如果与进程关联的等待句柄被标记为公共(public)而不是内部,这应该是可能的,因为它目前是 (vote here to ask Microsoft to change that) :
void BatchProcess()
{
Queue<string> queue = new Queue<string>();
queue.Enqueue("1.mp3");
queue.Enqueue("2.mp3");
queue.Enqueue("3.mp3");
...
queue.Enqueue("10000.mp3");
WaitHandle[] subprocesses = new WaitHandle[Math.Min(queue.Count, 5)];
for( int i = 0; i < subprocesses.Length; i++ ) {
subprocesses[i] = Spawn(queue.Dequeue());
}
while (queue.Count > 0) {
int j = WaitHandle.WaitAny(subprocesses);
subprocesses[j].Dispose();
subprocesses[j] = Spawn(queue.Dequeue());
}
WaitHandle.WaitAll(subprocesses);
foreach (var wh in subprocesses) {
wh.Dispose();
}
}
ProcessWaitHandle Spawn(string args)
{
using (Process p = new Process()) {
p.StartInfo.FileName = @"binary.exe";
p.StartInfo.Arguments = args;
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.Start();
return p.WaitHandle;
}
}
这可能是最有效的解决方案,因为除了 Win32 进程本身之外不需要同步对象。 C# 代码中不需要额外的线程,也不需要异步方法调用,因此不需要任何锁定或其他同步。
关于c# - 生成进程,但一次只有 5 个,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4360720/