添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

问题展示

大多数初次在C#中进行WPF程序写作的程序员,当代码涉及UI操作时可能会出现错误:

调用线程无法访问此对象,因为另一个线程拥有该对象

可以看到,我在 MainWindow 中创建了一个文本框对象 outputbox ,在使用如下代码进行操作时,返回该错误

this.outputbox.AppendText(msg);
this.outputbox.AppendText("\r\n");

究其原因,在WPF程序中,UI线程和后台线程分离,后台线程不能直接访问和修改UI层。WinForm按理说应该也是同样的线程分离方法,但是我在编写WinForm程序的时候没有出现这个问题,很奇怪。

解决方案

想要解决这个问题也很简单。在WPF程序中,引入了 Dispacher 用于管理线程工作项队列,可以简单把 Dispacher 理解为一个调度器。由于UI是由主线程创建的,而后台线程是子线程,所以后台线程不能直接访问UI对象,这时候只需要调用UI对象的 Dispacher.BeginInvoke 就可以把操作扔回UI线程执行,这样就不存在线程冲突的问题了。

this.outputbox.Dispatcher.BeginInvoke(new Action(() => { outputbox.AppendText(msg); }));
this.outputbox.Dispatcher.BeginInvoke(new Action(() => { outputbox.AppendText("\r\n"); }));

在将原代码改成上述代码后,程序顺利运行,没有再次出现错误。

碎碎念

发现了一个神奇的事情,在使用Fody以后线程冲突问题消失,原因未知...