我有一个进程,我可以启动,并且隐藏工作正常,但我想从控制台程序中读取,当我运行时,而不是之后,我试图运行一个计时器,anbd读取勾号,但我的程序只是崩溃,当它没有时,我什么都没得到。
startInfo= new ProcessStartInfo("cmd.exe");
startInfo.Arguments ="/C uus.exe "+ arg.ToString();
startInfo.RedirectStandardError = true;
startInfo.RedirectStandardOutput = true;
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
this.timer1.Enabled=true;
this.listBox1.Items.Clear();
p= Process.Start(startInfo);
Application.DoEvents();
void Timer1Tick(object sender, EventArgs e)
{
string str="";
str=p.StandardOutput.ReadLine();
if(str != null)
{
this.Text=str.ToString();
this.listBox1.Items.Add(str);
}
Application.DoEvents();
}
那我该怎么做才能解决这个问题呢?
更新的 我试过弯曲的建议 现在我的程序不再崩溃,但也没有收回任何数据
proc.StartInfo.UseShellExecute=false;
proc.StartInfo.CreateNoWindow=true;
proc.StartInfo.RedirectStandardOutput=true;
proc.StartInfo.RedirectStandardError=true;
proc.StartInfo.FileName="uus.exe";
proc.StartInfo.Arguments=arg;
proc.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(SortOutputHandler);
proc.Start();
proc.BeginOutputReadLine();
void SortOutputHandler(object o,System.Diagnostics.DataReceivedEventArgs e)
{
string str="";
string str2="";
str=e.Data.ToString();
if(str!=null && str!="")
{
this.listBox1.Items.Add(str.ToString());
this.Text=str.ToString();
}
str2=proc.StandardOutput.ReadLine();
if(str2!=null && str2!="")
{
this.lsw1.Items.Add(str2.ToString());
}
}
嗯?
更新的 我已经更改了处理程序,因为我已经告诉它,它不能这样做,它将是跨线程操作,如果是的话我们会发现错误。
private delegate void TextAdderDelegate(string str);
void TextAdder(string str)
{
if(this.lsw1.InvokeRequired==true)
{
Invoke(new TextAdderDelegate(TextAdder),new object[] {str});
}
else
{
this.lsw1.Items.Add(str);
}
}
void SortOutputHandler(object o,System.Diagnostics.DataReceivedEventArgs e)
{
string str="";
if(e!=null)
{
if(e.Data!=null)
{
str=e.Data.ToString();
}
}
TextAdder(str);
}
答案 0 :(得分:1)
问题是你在一个线程上运行并尝试使用另一个线程编写。当您使用Timer的tick事件创建后台线程时,它不能有前端用户输入。
也许如果你解释了你想要完成的事情的大局,我们可以更好地帮助你。
与此同时,您可能想要创建线程安全写入。这个article将帮助您理解在不同线程上写入表单控件的问题和解决方案。
答案 1 :(得分:0)
您可以显式创建Process实例(例如new Process
)并使用OutputDataReceived
事件,方法BeginOutputReadLine()
,并在完成CancelOutputRead()
时使用。
当输出数据可用时,事件OutputDataReceived
将从不同的线程重复调用。
答案 2 :(得分:0)
我假设您遇到'线程交叉异常',这可能是因为您正在更新其他线程上的表单控件然后更新UI线程。