error_reporting(0); error_reporting(E_ALL ^ E_WARNING);

登录后台

页面导航

本文编写于 457 天前,最后修改于 457 天前,其中某些信息可能已经过时。

问题展示

大多数初次在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以后线程冲突问题消失,原因未知...

歌曲封面
0:00