【问题标题】:Run .exe processes in parallel and update progress bar in .NET 4.5在 .NET 4.5 中并行运行 .exe 进程并更新进度条
【发布时间】:2016-12-17 08:56:35
【问题描述】:

我有一个 dataGridView,我在其中为每个条目运行一个 Process 然后根据 Process 的输出更新 toolStripProgressBar。

我看过以下主题,

Run two async tasks in parallel and collect results in .NET 4.5

Progress bar in parallel loop invocation

how to update the progress bar from tasks running concurrently

但我不确定如何将我当前的代码更改为这些代码。 在我看来,与这些线程的主要区别在于我的计算是由外部应用程序完成的, 然后我需要从中收集输出。 我想我必须将每个 Process 定义为一个异步任务,然后以某种方式收集输出。

为简单起见,示例代码中的过程权重相同。

private iNumProcesses; 
private void RunApps()
{
    iNumProcesses = dataGridView1.Rows.Count;
    string sPath = .exe application path    
    for (int i = 0; i < iNumProcesses; i++)
    {   
        string sArgs = dataGridView1.Rows[i]["Arguments"].ToString();
        ExecuteProgram(sPath, sArgs);
    }
}
private void ExecuteProgram(string sProcessName, string sArgs) 
{
    using (cmd = new Process())
    {
        cmd.StartInfo.FileName = sProcessName;
        cmd.StartInfo.Arguments = sArgs;
        cmd.StartInfo.UseShellExecute = false;
        cmd.StartInfo.CreateNoWindow = true;
        cmd.StartInfo.ErrorDialog = true;
        cmd.StartInfo.RedirectStandardOutput = true;
        cmd.StartInfo.RedirectStandardError = true;
        cmd.OutputDataReceived += new DataReceivedEventHandler(SortOutputHandler);
        cmd.ErrorDataReceived += new DataReceivedEventHandler(SortOutputHandler);
        cmd.Start();
        cmd.BeginOutputReadLine();
        while (!cmd.HasExited) { Application.DoEvents(); }
    }        
}
private void SortOutputHandler(object sender, DataReceivedEventArgs e)
{
    Trace.WriteLine(e.Data);
    this.BeginInvoke(new MethodInvoker(() =>
    {
        if (e.Data == "Start") { do something... }
        else if (e.Data == "Finish") { do something... }
        else if (e.Data == "End")   { do something... }
        else
        {
            // .exe application output numbers 1 through 100
            toolStripProgressBar1.Value += Math.Round(Convert.ToInt32(e.Data)/iNumProcesses,0);
        }
    }));
}

如何并行运行进程并更新进度条 基于我从 .exe 应用程序获得的输出数字 1 到 100? 任何意见或建议将不胜感激。

【问题讨论】:

    标签: c# .net multithreading process progress-bar


    【解决方案1】:

    我对这个问题的回答与“C#”特别相关,因此我不会直接用这些术语来说话:这个出人意料的棘手问题实际上是普遍存在的。

    • 您必须做的第一件事是安排定期更新用户显示。为避免令人讨厌的竞争条件和其他问题,您应该让“主线程”执行此任务,由毫秒计时器驱动。线程查询进度信息的共享数组并相应地更新所有进度条。 (如果您想使用事件来避免彻底的“定时等待”,请随意这样做。)

    • 由于每个启动的子进程都有自己的输入和输出流,并且会异步写入这些流,您会发现有必要生成一个“妈妈线程”在您的申请中监督每个孩子。这个线程对应于一个特定的外部进程,,事实上,它就是启动它的那个。线程继续存在,直到它确定它启动的进程已经死亡。

    • “妈妈线程”观察其指定病房的输出流以确定其“进度”。它相应地更新共享数组中的进度变量。 (此设计的一个关键要素是每个“妈妈线程”能够将 100% 的注意力集中在 孩子身上。而且,因为所有“妈妈”都是 线程, 他们可以轻松地与更新这些进度条的线程共享信息。)

    • 实际上是否必须使用信号量等来协调妈妈线程和主线程之间的访问?当然,取决于该数据结构的确切内部实现,答案可能是“可能不是。”(哦,但无论如何这样做可能是最安全的。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-03-29
      • 1970-01-01
      • 2019-04-04
      • 1970-01-01
      • 1970-01-01
      • 2011-06-12
      • 2022-07-15
      相关资源
      最近更新 更多