我有一个winform应用程序(一个窗体),在这个窗体上有一个RichTextBox.在这个表单的构造函数中,我创建了MyClass类的一个实例.在“Form_Load”中,我调用MyClass实例的初始化方法.
在表单构造函数中
myClass = new MyClass(RichTextBox richTextBox);
在Form_Load
myClass.Initialisation();
在初始化方法中,在循环中,我读了一些参数,做其他的东西.要冻结应用程序(因为某些操作可能需要一段时间,几秒钟),我使用了BackgroundWorker.我这样使用(见下面的代码).
当我执行,我得到这个错误:跨线程操作无效:控制’richTextBox’
从除了创建的线程之外的线程访问.
你能告诉我怎么解决这个问题吗?当我不访问richTextBox时,工作完美
public Class MyClass { static BackgroundWorker _bw; public MyClass() { _bw = new BackgroundWorker { WorkerReportsProgress = true,WorkerSupportsCancellation = true }; _bw.DoWork += bw_DoWork; _bw.ProgressChanged += bw_ProgressChanged; _bw.RunWorkerCompleted += bw_RunWorkerCompleted; } static void bw_DoWork(object sender,DoWorkEventArgs e) { foreach (....) { if (....) { richtextBox.Text.AppendText("MyText"); } } e.Result = true; } static void bw_RunWorkerCompleted(object sender,RunWorkerCompletedEventArgs e){} static void bw_ProgressChanged(object sender,ProgressChangedEventArgs e){} }
解决方法
使用BackgroundWorker不会免除您正常的线程规则,例如只有UI线程可以访问UI组件.
如果要从BackgroundWorker更新用户界面,而不是使用进度/完成事件(在UI线程上引发),则需要像其他情况一样使用Control.Invoke
/Control.BeginInvoke
.例如:
if (....) { Action action = () => richtextBox.Text.Add("MyText"); richtextBox.Invoke(action); // Or use BeginInvoke }