简体   繁体   中英

Process execution takes too long when it is called from WPF

I have the following code which opens command window (from WPF interface) and executes code where can take long like @ 8-10 minutes:

ProcessStartInfo procStartInfo = new ProcessStartInfo();
procStartInfo.FileName = _exePath;
procStartInfo.Arguments = arguments;
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = false;
procStartInfo.RedirectStandardOutput = true;
procStartInfo.RedirectStandardError = true;

using (Process pr = Process.Start(procStartInfo))
{
    pr.WaitForExit();
    string result = pr.StandardOutput.ReadToEnd();
    string[] split = result.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);

    int output = 0;
    int.TryParse(split[split.Length - 1], out output);

    return output;
}

And in Program.cs I have method which update status (show operation status and percent) with:

Console.Title = "Loading ... 5 %";

// do request to server and check status

while(status.InProgress) {
    Thread.Sleep(2000); // 2 seconds
    status = web.getJsonFromApiServer(url); // {InProgress: "true", Message: "Checking X%";       
}

Sometimes the process is hanged and its title is not updated anymore like something goes in infinite loop.

If I use console without starting from WPF ( I mean use command prompt and then set location to exe path and run it with arguments), it works fine, no issue.

Why does this thing happens ?

A deadlock condition can result if the parent process calls p.WaitForExit before p.StandardOutput.ReadToEnd and the child process writes enough text to fill the redirected stream. The parent process would wait indefinitely for the child process to exit. The child process would wait indefinitely for the parent to read from the full StandardOutput stream.

To avoid deadlocks you should use asynchronous methods:

var procStartInfo = new ProcessStartInfo
{
    FileName = _exePath,
    Arguments = arguments,
    UseShellExecute = false,
    CreateNoWindow = false,
    RedirectStandardOutput = true,
    RedirectStandardError = true
};
var p = new Process { StartInfo = procStartInfo };
p.OutputDataReceived += (sender, eventArgs) => { Console.WriteLine(eventArgs.Data); };
p.Start();
p.BeginOutputReadLine();
p.WaitForExit();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM