【问题标题】:System Threading: Cross-thread operation not valid系统线程:跨线程操作无效
【发布时间】:2012-04-13 12:17:03
【问题描述】:

我在线程中遇到的错误是:

跨线程操作无效。控件“richTextBox8”从创建它的线程以外的线程访问。

我将这段代码用于导致错误的字符串列表。

string[] parts = richTextBox8.Text.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);

现在我正在使用 System.Threading,它需要将上面的代码转换为类似于此代码的格式才能工作,但我无法做到这一点,或者有其他方法吗?

richTextBox8.Invoke((Action)(() => richTextBox8.Text += "http://elibrary.judiciary.gov.ph/" + str + "\n"));

【问题讨论】:

  • 您的第二个代码示例(或非常类似的代码)正是您所需要的。第二个代码有什么问题?
  • 你的文本框是什么类型的?我了解到一些第 3 方供应商在这种情况下存在问题
  • 理想情况下,您应该在开始线程操作之前获取richTextBox8.Text - 请给我们更多的上下文?
  • 嗨。第二个代码工作正常。我只想知道如何像第二个代码一样格式化第一个代码。
  • richTextBox8.Invoke((Action)(() => { /*do whatever you want */}));

标签: c# winforms multithreading


【解决方案1】:

您的字符串数组 (string[]) 对我来说看起来不错。如果在 RichTextBox8 中存在空格,它应该进行拆分。

关于您的线程,尝试使用委托,例如:

    public delegate void MyDelegate(string message);

   //when you have to use Invoke method, call this one:
   private void UpdatingRTB(string str)
   {
       if(richTextBox8.InvokeRequired)
           richTextBox8.Invoke(new MyDelegate(UpdatingRTB), new object []{ msg });
       else
           richTextBox8.AppendText(msg);
   }

【讨论】:

    【解决方案2】:
    string[] parts = null;
    richTextBox8.Invoke((Action)(() => 
        {
            parts = richTextBox8.Text.Split(new string[] { " " },
            StringSplitOptions.RemoveEmptyEntries); //added semicolon
        }));
    

    【讨论】:

      【解决方案3】:

      您只需要在 UI 线程上完成文本提取。

      variable capturing:

      string text = null;
      richTextBox8.Invoke((Action)(() => text = richTextBox8.Text));
      string[] parts = text.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
      

      没有变量捕获(效率稍高):

      var ret = (string)richTextBox8.Invoke((Func<string>)(() => richTextBox8.Text));
      parts = ret.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
      

      【讨论】:

      • 不客气。请注意,这比您选择的答案略高效,因为您不会在 UI 线程上进行拆分(通常,您希望尽可能远离 UI 线程)