过程比 CMD 需要更长的时间才能完成 [英] Process takes longer to finish than in CMD

查看:54
本文介绍了过程比 CMD 需要更长的时间才能完成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在运行一个程序,该程序运行 driverquery.exe 命令并取回输出

I am running a program that runs driverquery.exe command and gets back the ouput

        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 分钟才能完成.如果我通过 cmd 运行相同的过程,它总是在 2 分钟内完成.我曾尝试使用 readtoend 而不是 readline 但这也没有帮助.有人能说出这里有什么问题吗?在我的日志中,我可以看到最后一行被打印为 等待退出之前

The process takes about 30 minutes to finish.If i run the same process via cmd it always finishes in 2 minutes. I have tried using readtoend instead of readline but that also did not help. Can some tell what is wrong here? in my logs i can see the last line getting printed as before wait for exit

PS:当我在任务管理器中看到进程时,driverquery.exe 正在运行但不消耗任何 CPU 周期.调用此代码的进程消耗了大约 99% 的 CPU.我确信调用代码在运行此代码时没有执行任何其他任务.

PS: When i see the processes in the taskmanager the driverquery.exe is running but not consuming any CPU cycles. The process calling this code is consuming about 99% CPU. I know for sure that the calling code is not doing any other task while running this code.

推荐答案

我猜这个问题与:

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

您可能没有阅读应用程序的完整输出.如果它的输出有任何暂停,那么 reader.Peek() 在应用程序完成其完整输出之前返回 -1.如果它输出大量数据,您甚至可能会溢出输出流,因为您的进程在清空流后将放弃读取.如果是这种情况,子进程可能会生成大量异常输出到完整的流(这将大大增加执行时间).分析和调试会告诉你更多关于实际发生的事情.

You probably are not reading the full output of your application. If there is any pause in its output then reader.Peek() will return -1 before the application is finished its full output. If it is outputting a lot of data you may even be overflowing the output stream since your process will have given up reading after emptying the stream once. If this is the case, the child process may be generating a lot of exceptions outputting to a full stream (which will dramatically increase execution time). Profiling and debugging would tell you more about what is actually going on.

您可以尝试这样的异步方法:

You might try an async approach like this :

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 但线程池线程将处理传入的事件.

Rather than polling in a tight loop (which is likely to empty the output stream faster than the child process will fill it, and therefore fail), this waits for data to come in. Your main process will still block on the call to WaitForExit but a threadpool thread will handle the incoming events.

编辑

这是一个运行良好的 SSCCE :

Here is an SSCCE that works just fine :

    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 --> 输出:

Using outputRedirection as define above --> output :

如果这对您不起作用,请向我们展示您完整的真实代码.您正在做的其他事情是错误的.

If this isn't working for you, then please show us your complete, real code. Something else you are doing is wrong.

这篇关于过程比 CMD 需要更长的时间才能完成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆