文本框和Richtextbox在线程方面的区别

时间:2019-02-20 08:24:32

标签: c# .net winforms textbox richtextbox

我遇到了一个问题,我认为这可能是由于我的类将对象彼此传递的复杂性所致,所以我将其最小化,问题仍然存在:

我在VS2017社区中创建了一个默认的winform项目

在表单上,​​我添加了一个文本框,一个richtextbox,一个backgroundworker和一个用于激活background worker的按钮。

我将以下代码放入表单中,以填充文本框并在单击按钮时运行工作程序:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        textBox1.Text = "Hello";
        richTextBox1.Text = "World!";
    }

    private void button1_Click(object sender, EventArgs e)
    {
        if (backgroundWorker1.IsBusy != true)
        {
            backgroundWorker1.RunWorkerAsync();
        }
    }

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        MessageBox.Show(textBox1.Text);
        MessageBox.Show(richTextBox1.Text);
    }
}

我运行了程序,但我不知道接下来会发生什么。

textBox1.Text可从表单访问,因此MessageBox可以正常显示。 richTextBox1.Text无法访问,并给我这个错误:

  

跨线程操作无效:控制'richTextBox1'是从创建该线程的线程之外的其他线程访问的。

为什么?

我假设richTextBox具有更多的路由和换行功能,但是.Text属性是否不完全相同?这是怎么回事?

编辑:我不认为这与已标记的问题重复,因为他不是为TextBox.Text工作,而我是。我在问TextBox和RichTextBox .Text属性之间的区别。

2 个答案:

答案 0 :(得分:8)

它们的实现方式有所不同。

TextBox.Text基本上返回Control.Text,后者调用使用GetWindowText的{​​{3}}。  在代码注释中明确提到的可以调用GetWindowText跨线程。因此,他们通过设置标志inCrossThreadSafeCall来关闭有意检查跨线程的功能。

但是对于ReachTextBox.Text,它不依赖Control.TextWindowText发送EM_STREAMOUT并使用结果。因此,除了跨线程异常外,没有其他任何标志设置。

注意::您应该忽略这种情况,并且永远不要尝试从另一个线程访问UI元素。尝试与另一个线程中的UI线程进行交互时,请始终使用控件的Invoke方法。

答案 1 :(得分:1)

您必须Invoke UI代码(不能在UI之外的线程中运行UI):

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
   // What to do with UI
   Action action = () => {
      MessageBox.Show(textBox1.Text);
      MessageBox.Show(richTextBox1.Text);
   }

   if (InvokeRequired)  // We are in some background thread, Invoke required
     Invoke(action);
   else                 // We are in UI (main) thread, just call the action
     action(); 
}