簡體   English   中英

從WPF調用時,流程執行時間過長

[英]Process execution takes too long when it is called from WPF

我有以下代碼可以打開命令窗口(從WPF界面)並執行可能需要8-10分鍾才能完成的代碼:

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

Program.cs我有使用以下方法更新狀態(顯示操作狀態和百分比)的方法:

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%";       
}

有時進程會被掛起,並且其標題不再更新,就像發生無限循環一樣。

如果我使用控制台而不是從WPF開始(我的意思是使用命令提示符,然后將位置設置為exe路徑並使用參數運行它),那么它將正常工作,沒有問題。

為什么會發生這種事情?

如果父進程在p.StandardOutput.ReadToEnd之前調用p.WaitForExit,並且子進程寫入足夠的文本以填充重定向的流,則可能導致死鎖。 父進程將無限期地等待子進程退出。 子進程將無限期等待父進程從完整的StandardOutput流中讀取。

為了避免死鎖,您應該使用異步方法:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM