所以我一直在与这个问题作斗争一段时间,并尝试了许多不同的方法来解决它,但不能。
我的应用程序基本上是调用java文件来加载设备上的应用程序。当它将它打印到富文本框时,我想继续下一个文件。我遇到的问题是,当第一个文件被加载时,第二个文件尝试加载哪些情况问题。我已经尝试了等待退出,但如果我这样做,那么输出数据就不会被写入富文本框。有什么想法吗?
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加载下一个文件。
答案 0 :(得分:6)
如果您使用WaitForExit,您的应用程序将阻止(等待),直到进程退出。这意味着它无法在其UI线程中处理任何Windows消息,因此它不会更新UI。
您需要在“后台”启动该过程,以便您的UI继续刷新。这可以通过以下方式完成:
坐在忙碌的等待循环中直到完成,然后处理应用程序事件。 (请注意这一点,因为任何导致对此代码进行重入调用的事件都可能会造成非常糟糕的事情。通常,如果您使用此方法,您需要确保应用程序的其余部分在其知道的状态下“锁定”正在忙着等待一个过程完成)。这实际上是WaitForExit所做的,但它也处理应用程序事件,允许UI保持模糊的响应:
while (!process.HasExited)
{
Application.DoEvents();
Thread.Sleep(100);
}
答案 1 :(得分:0)
我在这里可能完全错了,但是......
process1.StartInfo.Arguments = "-Xmx512M -jar";
process1.StartInfo.Arguments += toLoad;
您需要在-jar
否则Java会立即炸掉。
答案 2 :(得分:0)
尝试将WaitForExit
调用移出UI线程。
作为@M。 Babcock提到,你正在对富文本框进行更新。
类似的解决方案可能有效:
修改btnLoad_Click
以启动一个处理列表的新线程(这将在count&gt; 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.
}
答案 3 :(得分:0)
正如建议的那样 here,设置process.EnableRaisingEvents = true解决了我的情况下被阻止的ui的问题。