处理时间比在CMD完成(Process takes longer to finish than in

2019-10-19 15:56发布

我正在运行driverquery.exe命令和回来的输出中的程序

        pProcess.StartInfo.CreateNoWindow = true;
        debugLog.WriteToLog("");
        pProcess.StartInfo.UseShellExecute = false;
        pProcess.StartInfo.RedirectStandardOutput = true;
        pProcess.StartInfo.WindowStyle =  System.Diagnostics.ProcessWindowStyle.Hidden;
        debugLog.WriteToLog("before start method");
        pProcess.Start();
        debugLog.WriteToLog("after start method");
        if (windowTitleToHide.Length > 0)
        {
            WindowsUtil.HideWindow(windowTitleToHide);
        }
        if (null != attributeName && !"".Equals(attributeName))
            Console.WriteLine(attributeName + " : ");
        debugLog.WriteToLog("before read to end");

        StreamReader reader = pProcess.StandardOutput;
        String strOutput = string.Empty;

        while (reader.Peek() > -1)
            strOutput += reader.ReadLine();

        debugLog.WriteToLog("after read to end");
        Console.WriteLine(strOutput);
        debugLog.WriteToLog("before wait for exit");
        pProcess.WaitForExit();
        debugLog.WriteToLog("after wait for exit");
        pProcess.Close();

该过程需要约30分钟至finish.If我运行经由CMD它总是在2分钟内完成相同的处理。 我一直在使用ReadToEnd的,而不是尝试过的ReadLine但也没有帮助。 可有些分不清什么是错在这里? 在我的日志,我可以看到的最后一行得到打印为等待退出前

PS:当我在任务管理器看到进程driverquery.exe正在运行,但不消耗任何CPU周期。 调用此代码的过程耗时约99%的CPU。 我知道肯定调用代码是没有做任何其他的任务,同时运行这段代码。

Answer 1:

我可能会想这个问题是关系到:

while (reader.Peek() > -1)
    strOutput += reader.ReadLine();

你可能不读您的应用程序的完整输出。 如果在它的输出,那么任何停顿reader.Peek() 返回-1应用程序之前完成其全部的输出。 如果是输出大量的数据,你甚至可能会溢出输出流,因为你的进程将再次放空流之后已经放弃了读书。 如果是这样的话,子进程可能会产生大量的异常输出到全流(这将显着增加执行时间)。 分析和调试会告诉你更多关于什么是真正回事。

你可以尝试这样的做法异步:

pProcess.StartInfo.RedirectStandardOutput = true;
pProcess.EnableRaisingEvents = true;  // Enable events
pProcess.OutputDataReceived += outputRedirection; // hook up
pProcess.Start();
pProcess.BeginOutputReadLine();  // use async BeginOutputReadLine
pProcess.WaitForExit();

哪里

static void outputRedirection(object sendingProcess, 
                              DataReceivedEventArgs outLine)
{
    try
    {
        if (outLine.Data != null)
            Console.WriteLine(outLine.Data);
            // or collect the data, etc
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
        return;
    }
}

而不是在紧密循环(这很可能是空输出流比子进程加快将填补它,因此失败)轮询,这个等待数据进来,你的主要过程仍然会在电话会议上阻止WaitForExit但一个线程池线程将处理传入的事件。

编辑

下面是一个SSCCE的作品就好了:

    static void Main(string[] args)
    {            
        Stopwatch spw = new Stopwatch();
        spw.Start();
        Process pProcess = new Process();
        pProcess.StartInfo.FileName = "driverquery.exe";
        pProcess.StartInfo.CreateNoWindow = true;
        pProcess.StartInfo.UseShellExecute = false;
        pProcess.StartInfo.RedirectStandardOutput = true;
        pProcess.EnableRaisingEvents = true;
        pProcess.OutputDataReceived += outputRedirection;
        pProcess.Start();
        pProcess.BeginOutputReadLine();
        pProcess.WaitForExit();        
        pProcess.Close();
        spw.Stop();
        Console.WriteLine();
        Console.WriteLine("Completed in : " + 
                           spw.ElapsedMilliseconds.ToString() 
                           + "ms");
    }

使用outputRedirection上文中所定义- >输出:

如果这不是为你工作,那么请告诉我们您的完整的,真正的代码。 别的东西,你正在做的是错的。



文章来源: Process takes longer to finish than in CMD