所以我得到这个跨线程错误,我无法弄明白。在我尝试使用它之前,这是我的基本代码。
基本上代码是调用批处理文件然后调用java文件。然后输出数据实时重定向到控制台。当我只是将输出重定向到C#控制台时,它工作正常。但是我希望将相同的信息打印到应用程序中的富文本框中。 VS 2010抱怨rchsdtOut.Text = e.Data.ToString(); 跨线程操作无效:控制'rchsdtOut'从其创建的线程以外的线程访问。
我已经尝试过这样做了,我承认我是线程新手,所以任何有关如何轻松完成此任务的帮助都将不胜感激。
//Declare and instantiate a new process component.
System.Diagnostics.Process process1;
process1 = new System.Diagnostics.Process();
process1.StartInfo.UseShellExecute = false;
process1.StartInfo.RedirectStandardOutput = true;
process1.StartInfo.CreateNoWindow = true;
process1.StartInfo.FileName = "cmd.exe";
process1.StartInfo.Arguments = "BATFile.bat";
process1.OutputDataReceived += (s, a) => myMethod(a);
process1.Start();
process1.BeginOutputReadLine();
process1.WaitForExit();
process1.Close();
private void myMethod(DataReceivedEventArgs e) {
if (e.Data != null)
{
rchsdtOut.Text = e.Data.ToString();
Console.WriteLine(e.Data.ToString());
}
}//end of private
答案 0 :(得分:6)
试试这一行:
process1.OutputDataReceived += (s, a) => rchsdtOut.Invoke(new System.Action(()=> myMethod(a)));
答案 1 :(得分:5)
从其创建的线程以外的线程访问WinForms控件是不合法的。您需要使用Invoke
或BeginInvoke
来控制回适当的线程。
private void myMethod(DataReceivedEventArgs e) {
if (e.Data != null) {
Action action = () => rchstdOut.Text = e.Data.ToString();
rchstdOut.Invoke(action, null);
Console.WriteLine(e.Data.ToString());
}
}
答案 2 :(得分:0)
只有在从另一个方法调用方法时,才能从UI线程升级rchsdtOut
。
有几种解决方案。如果你想有一个更新控件的通用方法,你可以检查控件。InvokeRequired属性(或WPF中的this.Dispatcher.CheckAccess())并使用委托。
private delegate void UpdateTextControlDelegate(Control control, string text);
private void UpdateTextControl(Control control, string text)
{
if (control.InvokeRequired)
{
Invoke(new UpdateTextControlDelegate(UpdateTextControl), new object[] { control, text});
return;
}
control.Text = text;
}
...
if (e.Data != null)
{
UpdateTextControl(rchsdtOut, e.Data.ToString());
Console.WriteLine(e.Data.ToString());
}
答案 3 :(得分:0)
您无法从创建它的位置以外的线程访问表单控件。 您将需要创建两个线程都可以访问的其他对象。 Producer Consumer Problem