等待多个进程完成
本文关键字:进程 等待 | 更新日期: 2023-09-27 18:35:34
我希望我的程序等待所有进程完成,然后删除一些临时文件。我已经有一段代码可以在一次处理一个进程时执行此操作,但我无法使其适用于多个进程。
我将首先展示有效的代码。此代码正确运行进程,等待它完成,然后删除临时文件:
foreach (string script in scriptList)
{
ProcessStartInfo myProcess = new ProcessStartInfo();
myProcess.FileName = accoreconsolePath;
myProcess.Arguments = "/s '"" + script + "'"";
myProcess.CreateNoWindow = true;
Process myWait = Process.Start(myProcess);
myWait.WaitForExit();
File.Delete(script);
}
以上内容整齐地包含在foreach
循环中。我无法工作的是它的并行版本,其中等待语句位于foreach循环之外:
Process myWait;
foreach (string script in scriptList)
{
ProcessStartInfo myProcess = new ProcessStartInfo();
myProcess.FileName = accoreconsolePath;
myProcess.Arguments = "/s '"" + script + "'"";
myProcess.CreateNoWindow = true;
myWait = Process.Start(myProcess);
}
myWait.WaitForExit(); //error: use of unassigned local variable "myWait"
//delete file would go here
我想我只需要在进入foreach
循环之前初始化myWait
,但我不知道该怎么做。如何在不将其分配给任何内容的情况下初始化进程?还有其他简单的方法可以做到这一点吗?
不确定这种方法是否在评论中的任何链接问题中,但这里有一个利用List<Task>
和 Task.WaitAll():
List<Task> tasks = new List<Task>();
foreach (string script in scriptList)
{
string tmpScript = script;
tasks.Add(Task.Run(delegate {
ProcessStartInfo myProcess = new ProcessStartInfo();
myProcess.FileName = accoreconsolePath;
myProcess.Arguments = "/s '"" + tmpScript + "'"";
myProcess.CreateNoWindow = true;
Process.Start(myProcess).WaitForExit();
File.Delete(tmpScript);
}));
}
Task.WaitAll(tasks.ToArray());
我会将进程句柄存储在脚本与进程句柄的字典中,然后等待所有进程退出。下面是代码:
var processes = new Dictionary<string,Process>();
foreach (string script in scriptList)
{
ProcessStartInfo myProcess = new ProcessStartInfo();
myProcess.FileName = accoreconsolePath;
myProcess.Arguments = "/s '"" + script + "'"";
myProcess.CreateNoWindow = true;
myWait = Process.Start(myProcess);
processes.Add(script, myWait);
}
foreach(var script in processes.Keys)
{
Process process = processes[script];
process.WaitForExit();
process.Close();
File.Delete(script);
}
未来观众的替代方式:
var NoOfCores = 4;
Parallel.For(0, scriptList.Count,new ParallelOptions {MaxDegreeOfParallelism=NoOfCores }, index =>
{
Process proc= new Process();
proc.StartInfo.FileName = "filename";
proc.StartInfo.WorkingDirectory = "optional";
proc.StartInfo.Arguments = scriptList[index];
proc.Start();
proc.WaitForExit();
//code here will be executed after finishing each thread
}
//code here will be executed after finishing all the threads
或使用 Parallel.ForEach
var NoOfCores = 4;
Parallel.For(0, scriptList,new ParallelOptions {MaxDegreeOfParallelism=NoOfCores }, script=>
{
Process proc= new Process();
proc.StartInfo.FileName = "filename";
proc.StartInfo.WorkingDirectory = "optional";
proc.StartInfo.Arguments = script;
proc.Start();
proc.WaitForExit();
//code here will be executed after finishing each thread
}
//code here will be executed after finishing all the threads