【问题标题】:Wait for multiple processes to complete等待多个进程完成
【发布时间】:2015-02-25 04:09:51
【问题描述】:

我希望我的程序等待所有进程完成,然后删除一些临时文件。我已经有一段代码可以在一次处理一个进程时执行此操作,但我无法使其适用于多个进程。

我将首先展示有效的代码。此代码正确运行一个进程,等待它完成,然后删除临时文件:

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 循环中。我无法工作的是 parallel 版本,其中等待语句位于 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,但我不知道该怎么做。如何初始化进程而不将其分配给任何东西?还有其他一些简单的方法可以做到这一点吗?

【问题讨论】:

标签: c# process parallel-processing wait


【解决方案1】:

不确定这种方法是否存在于 cmets 的任何链接问题中,但这里有一个使用 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());

【讨论】:

    【解决方案2】:

    我会将进程句柄存储在脚本与进程句柄的字典中,然后等待所有进程退出。下面是代码:

    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);
    }
    

    【讨论】:

    • Dictionary&lt;TKey, TValue&gt; 上迭代 TKey 并将第一行作为 TValue 的分配与在字典上迭代 Pair&lt;TKey, TValue&gt; 并使用 KeyValue 属性,除非您避免使用散列算法。
    【解决方案3】:

    未来观众的另一种方式:

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-06
      • 2017-08-03
      • 1970-01-01
      • 2011-11-09
      相关资源
      最近更新 更多