WaitforExit无法正常工作

所以我一直在争论这个问题一段时间,并尝试了许多不同的方法来解决它,但不能。

基本上我的应用程序是调用java文件来加载设备上的应用程序。 当它正在加载它将它打印到richtext框时,我想转到下一个文件。 我遇到的问题是,当第一个文件被加载时,第二个文件尝试加载哪些情况问题。 我已经尝试了等待退出,但如果我这样做,那么输出数据就不会写入富文本框。 有任何想法吗?

private void btnLoad_Click(object sender, EventArgs e) { rchsdtOut.Clear(); //count the items in queue. var count = lstBarToLoad.Items.Count; if (count <= 0) { MessageBox.Show("Nothing added to the load queue"); } else { String toLoad; for (int i=0; i < count;i++) {//START OF FOREACH toLoad = lstBarToLoad.Items[i].Text; //call load method. loaddPB(toLoad); }//end of for. }//end of else. }//end of private 

我尝试在许多不同的地方等待退出,但它似乎不起作用。

  //Method to load files on device. private void loaddPB(string toLoad) { process1 = new System.Diagnostics.Process(); process1.StartInfo.UseShellExecute = false; process1.StartInfo.RedirectStandardOutput = true; process1.StartInfo.RedirectStandardError = true; process1.StartInfo.CreateNoWindow = true; process1.StartInfo.FileName = "java.exe "; process1.StartInfo.Arguments = "-Xmx512M -jar"; process1.StartInfo.Arguments += toLoad; try { process1.Start(); process1.OutputDataReceived += (s, a) => myMethod(a); process1.BeginOutputReadLine(); process1.ErrorDataReceived += (s, a) => myErrorMethod(a); process1.BeginErrorReadLine(); process1.WaitForExit(); } catch { Console.WriteLine("error"); } } 

下面两种方法将stdout或错误写入richtext字段。

  //Method to do the logging. private void myMethod(DataReceivedEventArgs e) { if (e.Data != null) { Action action = () => rchsdtOut.Text += "\r\n" + e.Data.ToString(); rchsdtOut.BeginInvoke(action, null); Console.WriteLine(e.Data.ToString()); } }//end of private //Method to load the error if any thrown. private void myErrorMethod(DataReceivedEventArgs e) { if (e.Data != null) { Action action = () => rchsdtOut.Text += "\r\n" + e.Data.ToString(); rchsdtOut.BeginInvoke(action, null); Console.WriteLine(e.Data.ToString()); } }//end of private 

任何想法都会很棒。 基本上我需要进程退出,所以我可以继续认为forloop加载下一个文件。

如果您使用WaitForExit,您的应用程序将阻塞(等待),直到该进程退出。 这意味着它无法在其UI线程中处理任何Windows消息,因此它不会更新UI。

您需要“在后台”启动该过程,以便您的UI继续刷新。 这可以通过以下方式完成:

  • 从单独的线程启动并监视进程,并将进度信息传递回UI线程以供显示
  • 向进程退出事件添加事件处理程序,或定期轮询process.HasExited标志,并使用它来了解第一个进程何时完成。 您的事件处理程序将关闭此进程,然后退回到主应用程序循环,以便在等待外部进程完成时正常运行。
  • 坐在忙碌的等待循环中直到它完成,并处理应用程序事件。 (请注意这一点,因为任何导致重新调用此代码的事件都可能会造成非常糟糕的事情。通常,如果您使用此方法,您需要确保应用程序的其余部分在其知道的状态下“锁定”正在忙着等待一个过程完成)。 这实际上是WaitForExit所做的,但它也处理应用程序事件,允许UI保持模糊响应:

     while (!process.HasExited) { Application.DoEvents(); Thread.Sleep(100); } 

我在这里可能完全错了,但……

 process1.StartInfo.Arguments = "-Xmx512M -jar"; process1.StartInfo.Arguments += toLoad; 

你需要在-jar之后有一个空格

否则Java会立即炸毁。

尝试将WaitForExit调用移出UI线程。

作为@M。 Babcock提到,你正在对富文本框进行更新。

类似于此的解决方案可能有效:

修改btnLoad_Click以启动一个处理列表的新线程(这在count> 0分支中)

 Thread thread = new Thread(new ThreadStart(LoadPbThread)); thread.Start(); 

然后,添加:

 void LoadPbThread() { String toLoad; for (int i=0; i < count;i++) {//START OF FOREACH toLoad = lstBarToLoad.Items[i].Text; //call load method. loaddPB(toLoad); }//end of for. } 

正如这里所建议的,设置process.EnableRaisingEvents = true解决了我的情况下被阻止的ui的问题。