我遇到了一个问题,我认为这可能是由于我的类的复杂性将对象传递给对方所以我最小化它并且问题仍然存在:
我有一个在VS2017社区中创建的默认winform项目
在表单上我添加了一个文本框,一个richtextbox,一个backgroundworker和一个用于激活后台工作者的按钮.
我在表单中放入以下代码来填充文本框并在按钮单击时运行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不可访问,并给我这个错误:
Cross-thread operation not valid: Control ‘richTextBox1’ accessed from a thread other than the thread it was created on.
为什么?
我假设richTextBox有更多的路由和包装但是.Text属性不完全相同?!这里发生了什么?
编辑:我不认为这是一个重复的标记问题,因为他没有为TextBox.Text工作,而我的.我问的是TextBox和RichTextBox .Text属性之间的区别.
解决方法:
它们的实现方式不同.
TextBox.Text基本上返回Control.Text,它调用WindowText
使用GetWindowText.
在代码注释中明确提到可以调用GetWindowText跨线程.因此,他们通过在CrossThreadSafeCall中设置标志来关闭有意识的跨线程检查.
但对于ReachTextBox.Text,它不依赖于Control.Text. It发送EM_STREAMOUT并使用结果.因此除了跨线程异常之外没有设置任何标志.
注意:您应该忽略这种情况,并且永远不要尝试从另一个线程访问UI元素.当您尝试与另一个线程的UI线程交互时,始终使用控件的Invoke方法.