簡體   English   中英

C#等待重定向的所有日期

[英]C# Wait for all dates from redirecting

我將輸出從進程(proc)重定向到richtextbox(richTextBoxOutput)。 重定向之前,它將寫入Richtextbox語句“輸出數據之前”。 然后,它應寫入過程中的所有數據,並寫“ AFTER OUTPUT DATA”之后。 但是,最后一句話永遠不會結束。 它始終位於重定向日期之間RichTextBox的中間。 您能幫我解決問題嗎?

richTextBoxOutput.AppendText("BEFORE OUTPUT DATA");
Process proc = new Process();
proc.StartInfo.FileName = command;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.CreateNoWindow = true;
proc.OutputDataReceived += new DataReceivedEventHandler
(
            (s, e) =>
            {
                if (richTextBoxOutput.InvokeRequired)
                {
                    richTextBoxOutput.Invoke(new Action(() => richTextBoxOutput.AppendText(e.Data + "\n")));
                }
                else
                    richTextBoxOutput.AppendText(e.Data + "\n");
            }
);
proc.ErrorDataReceived += new DataReceivedEventHandler((s, e) => { richTextBoxOutput.AppendText(e.Data + "\n"); });
proc.Start();
proc.BeginOutputReadLine();
while (!proc.HasExited)
{
        Application.DoEvents(); //Instead of proc.WaitForExit()             
}
richTextBoxOutput.AppendText("AFTER OUTPUT DATA");

我可以建議采用異步方法解決此問題嗎?
是的,您將不得不處理跨線程調用,因為您正在從另一個線程寫入Windows窗體(類似於文本框)組件,但好處是您可以使用proc.WaitForExit而不必擔心凍結接口(不必擔心討厭的接口)循環效率極低,因為它將使您的應用程序耗盡CPU的電量),並具有ContinueWith子句以附加“ AFTER OUTPUT DATA”!

最少的工作樣本:

    private void btnRun_Click(object sender, EventArgs e) {
        Task.Factory.StartNew(this.StdOutWorker);
    }

    private void StdOutWorker() {
        this.AppendLine("BEFORE OUTPUT DATA");

        // "CmdRandomGenerator.exe" will print random numbers to standard output in infinity loop
        ProcessStartInfo pi = new ProcessStartInfo("CmdRandomGenerator.exe") {
            RedirectStandardOutput = true,
            UseShellExecute = false
        };
        var proc = new Process{
            StartInfo = pi,
            EnableRaisingEvents = true
        };
        proc.Start();

        while (!proc.HasExited) {
            var line = proc.StandardOutput.ReadLine();
            this.AppendLine(line);
        }

        this.AppendLine("AFTER OUTPUT DATA");
    }

    private void AppendLine(string line) {
        Action act = () => {
            this.rtbOutput.AppendText(line + Environment.NewLine);
        };

        // UI objects must be accessed in UI thread
        this.BeginInvoke(act);
    }

想法是,從進程中進行讀取是在后台線程中進行的,並且將值傳遞到UI線程時無需等待結果(即發即忘)。

從理論上講,來自觀察到的過程的值可能比UI可以處理的更快。 在這種情況下,您必須丟棄一些值(采樣)。 但是我用while(true) { Console.WriteLine(random()); } while(true) { Console.WriteLine(random()); } ,用戶界面的速度較慢,但​​仍然可以響應。

暫無
暫無

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

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