C# WaitforExit没有';我不能正常工作
因此,我已经与这个问题斗争了一段时间,并尝试了许多不同的方法来解决它,但不能 基本上,我的应用程序所做的就是调用java文件在设备上加载应用程序。当它加载的时候,它正在打印到一个richtext框中,然后我想转到下一个文件。我遇到的问题是,在加载第一个文件时,第二个文件会尝试加载出现问题的案例。我尝试了等待退出,但是如果我这样做,那么输出数据就不会写入富文本框。有什么想法吗C# WaitforExit没有';我不能正常工作,c#,waitforexit,C#,Waitforexit,因此,我已经与这个问题斗争了一段时间,并尝试了许多不同的方法来解决它,但不能 基本上,我的应用程序所做的就是调用java文件在设备上加载应用程序。当它加载的时候,它正在打印到一个richtext框中,然后我想转到下一个文件。我遇到的问题是,在加载第一个文件时,第二个文件会尝试加载出现问题的案例。我尝试了等待退出,但是如果我这样做,那么输出数据就不会写入富文本框。有什么想法吗 private void btnLoad_Click(object sender, EventArgs e) {
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
以下两种方法将标准输出或错误写入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加载下一个文件。我可能完全错了,但是
process1.StartInfo.Arguments = "-Xmx512M -jar";
process1.StartInfo.Arguments += toLoad;
您需要在-jar
否则Java将立即崩溃。如果您等待ForExit,您的应用程序将阻塞(等待)直到进程退出。这意味着它无法在其UI线程中处理任何Windows消息,因此不会更新UI 您需要“在后台”启动该过程,以便您的UI继续刷新。这可以通过以下方式实现:
- 从单独的线程启动并监视进程,并将进度信息传递回UI线程以供显示
- 将事件处理程序添加到process exited事件,或定期轮询process.HasExited标志,并使用该标志了解第一个进程何时完成。您的事件处理程序将启动此进程,然后退出回主应用程序循环,以便它在等待外部进程完成时正常运行
- 坐在一个繁忙的等待循环中,直到它完成,并处理应用程序事件。(注意这一点,因为任何导致对该代码的可重入调用的事件都可能造成非常糟糕的后果。通常,如果使用这种方法,您需要确保应用程序的其余部分处于“锁定”状态,它知道自己正忙着等待某个进程完成)。WaitForExit实际上就是这样做的,但它也处理应用程序事件,使UI保持模糊响应:
while (!process.HasExited) { Application.DoEvents(); Thread.Sleep(100); }
WaitForExit
调用移出UI线程
正如@M.Babcock所提到的,您正在等待富文本框的更新
类似的解决方案可能会奏效:
ModifybtnLoad\u单击
启动一个处理列表的新线程(进入count>0分支)
然后,添加以下内容:
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.
}
void LoadPbThread()
{
字符串加载;
for(int i=0;i
正如所建议的那样
,设置process.EnableRaisingEvents=true解决了我的问题。请避免在问题标题前加上“C#”之类的前缀,这就是标记的用途。将.NET版本作为标记可能会有所帮助,同样。将
loaddPB
的执行移出UI线程,然后WaitForExit
将不会阻止对富文本框的更新。您是否收到任何类型的错误消息?在我看来,您的参数是-Xmx512M-jar{0}
,在-jar
命令行选项后缺少一个空格。这可能会导致它由于无法理解命令而立即退出。此外,正如M.Babcock所建议的,将loaddPB
方法从UI线程中移出,并确保将加载部分包装在信号灯中,这样一来,一次只加载一个文件,UI可以继续执行它需要执行的操作。我从jar命令中删除了其余的命令,因为我不认为这是公开的。我删除了其余的java代码,因为我不希望它被公开。谢谢Jason。这是一个非常详细的回答,现在有意义了。我在上面添加了代码,它看起来像一个符咒。我已经为此奋斗了几天,非常感谢您的帮助。请注意,这有点“黑客”,因为您仍在阻止UI线程,但您正在通过消息队列手动泵送事件。这不是一个最佳实践,大多数开发人员都会建议不要这样做。最好的选择是将加载代码抛出到一个单独的线程中。@SPFiredrake:同意。这就是为什么它被列为我的第三个选择,并包括一个警告。(这是一个实用但相当肮脏和危险的解决方案)
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.
}