【发布时间】:2019-07-13 20:58:21
【问题描述】:
我遇到了一个问题,我认为这可能是由于我的类相互传递对象的复杂性,所以我将其最小化并且问题仍然存在:
我在 VS2017 社区中创建了一个默认的 winform 项目
在表单上,我添加了一个文本框、一个富文本框、一个后台工作程序和一个用于激活后台工作程序的按钮。
我已将以下代码放入表单中以填充文本框并在单击按钮时运行工作程序:
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 属性之间的差异。
【问题讨论】:
-
永远不要从后台线程访问 UI 线程元素。
TextBox和RichTextBox都不是。DoWork处理程序中的代码肯定是错误的。你应该使用ReportProgress并在那里做你的事情。 -
是的,我知道,当我运行异步工作程序时,我实际上是通过参数传递的。这是我正在查看的旧代码,我仍然想回答我的问题!
-
答案是UI控件不是线程安全的,至于它们如何反应,不可预测,没什么好说的了。
-
TextBoxworks 巧合,你是幸运当前实现没有抛出的。你不应该依赖这样的测试。所有 UI 元素都必须从创建它们的同一线程访问。
标签: c# .net winforms textbox richtextbox