
private voID runconsoleApp(){ Process proc = new Process(); proc.StartInfo.filename = "app.exe"; proc.StartInfo.Arguments = "-a -b -c"; proc.StartInfo.UseShellExecute = false; // set up output redirection proc.StartInfo.RedirectStandardOutput = true; proc.StartInfo.RedirectStandardError = true; proc.EnableRaisingEvents = true; proc.StartInfo.CreateNowindow = true; // Set the data received handlers proc.ErrorDataReceived += proc_DataReceived; proc.OutputDataReceived += proc_DataReceived; proc.Start(); proc.BeginErrorReadline(); proc.BeginoutputReadline(); proc.WaitForExit(); if (proc.ExitCode == 0) { out_txtbx.AppendText("Success." + Environment.Newline); } else { out_txtbx.AppendText("Failed." + Environment.Newline); }} 然后使用此输出处理程序捕获和处理数据,
// Handle the date received by the console processvoID proc_DataReceived(object sender,DataReceivedEventArgs e){ if (e.Data != null) { if ((e.Data.EndsWith("DONE.")) || (e.Data.EndsWith("Failed.")) || (e.Data.StartsWith("reset"))) { // This crashes the application,but is supposedly the correct method this.AppendText(e.Data + Environment.Newline); // This works,but the deBUGger keeps warning me that the call // is not thread safe //out_txtbx.AppendText(e.Data + Environment.Newline); } }} 然后像这样追加控制台文本,
delegate voID AppendTextDelegate(string text);// Thread-safe method of appending text to the console Boxprivate voID AppendText(string text){ // Use a delegate if called from a different thread,// else just append the text directly if (this.out_txtbx.Invokerequired) { // Application crashes when this line is executed out_txtbx.Invoke(new AppendTextDelegate(this.AppendText),new object[] { text }); } else { this.out_txtbx.AppendText(text); }} 从我看到的所有文档和示例看来,这似乎是正确的方法,除了它在调用out_txtbx.Invoke时崩溃应用程序.
什么可以被打破,有什么替代方法可以做到这一点?
解决方案(正如Hans Passant所指出的那样)
问题是该应用程序由于线路而陷入“致命的拥抱”,
proc.WaitForExit();
该行应删除,方法应如下所示,
private voID runconsoleApp(){ Process proc = new Process(); proc.StartInfo.filename = "app.exe"; proc.StartInfo.Arguments = "-a -b -c"; proc.StartInfo.UseShellExecute = false; // set up output redirection proc.StartInfo.RedirectStandardOutput = true; proc.StartInfo.RedirectStandardError = true; proc.EnableRaisingEvents = true; proc.StartInfo.CreateNowindow = true; // Set the data received handlers proc.ErrorDataReceived += proc_DataReceived; proc.OutputDataReceived += proc_DataReceived; // Configure the process exited event proc.Exited += new EventHandler(ProcExited); proc.Start(); proc.BeginErrorReadline(); proc.BeginoutputReadline(); // This blocks the main thread and results in "deadly embrace" // The Process.Exited event should be used to avoID this. //proc.WaitForExit();} 并应提供事件处理程序,
/// <summary>/// Actions to take when console process completes/// </summary>private voID ProcExited(object sender,System.EventArgs e){ Process proc = (Process)sender; // Wait a short while to allow all console output to be processed and appended // before appending the success/fail message. Thread.Sleep(40); if (proc.ExitCode == 0) { this.AppendText("Success." + Environment.Newline); ExitBootloader(); } else { this.AppendText("Failed." + Environment.Newline); } proc.Close();}解决方法 proc.WaitForExit();
它被称为死锁.您的主线程被阻止,等待进程退出.这使它无法承担基本职责.就像保持UI更新一样.并确保调度Control.Invoke()请求.这会阻止AppendText()方法完成.这会停止退出的过程.这会阻止你的UI线程通过WaitForExit()调用. “致命的拥抱”,又名死锁.
你不能阻止你的主线程.请改用Process.Exited事件.
总结以上是内存溢出为你收集整理的c# – 如何以线程安全的方式将控制台程序的输出重定向到文本框?全部内容,希望文章能够帮你解决c# – 如何以线程安全的方式将控制台程序的输出重定向到文本框?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)