跨线程操作无效:Control';rchsdtOut';从创建它的线程以外的线程访问
本文关键字:线程 操作 访问 创建 无效 rchsdtOut Control | 更新日期: 2023-09-27 18:20:53
所以我得到了这个跨线程错误,我无法解决它。这是我试图篡改它之前的基本代码。
基本上,代码要做的是调用一个批处理文件,然后再调用一个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
试试这一行:
process1.OutputDataReceived += (s, a) => rchsdtOut.Invoke(new System.Action(()=> myMethod(a)));
从创建WinForms控件的线程以外的线程访问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());
}
}
您不能从创建表单控件的线程以外的线程访问表单控件。您将需要创建两个线程都可以访问的其他对象。生产者-消费者问题
当您的方法从另一个线程调用时,只能从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());
}