跨线程操作无效:控制'rchsdtOut'从其创建的线程以外的线程访问

时间:2012-01-19 17:30:25

标签: c#

所以我得到这个跨线程错误,我无法弄明白。在我尝试使用它之前,这是我的基本代码。

基本上代码是调用批处理文件然后调用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

4 个答案:

答案 0 :(得分:6)

试试这一行:

process1.OutputDataReceived += (s, a) => rchsdtOut.Invoke(new System.Action(()=> myMethod(a)));

答案 1 :(得分:5)

从其创建的线程以外的线程访问WinForms控件是不合法的。您需要使用InvokeBeginInvoke来控制回适当的线程。

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