为什么 UI 元素必须始终从 UI 线程创建/更新?

7

为什么UI元素必须始终从UI线程创建/更新?

在(几乎?)所有编程语言中,只有从UI线程才能安全地访问/修改UI元素。我理解这是标准的并发访问和同步问题,但这真的是必要的吗?这种行为是由编程语言还是操作系统强制实施的?是否有任何编程语言中的情况不同?

3个回答

9

这是由图形框架所强制执行的 - 这通常(但并非总是)由操作系统提供。

基本上,使所有东西“正确地线程安全”是低效的。虽然必须将调用返回到UI线程可能很烦人,但它允许UI线程自身快速处理事件,而无需担心锁定等问题。


难道让框架自己进行检查和调用的封装不是更简单吗?这样至少可以避免在第一时间就有人以不安全的方式调用它,.Net框架本来可以为我们做这个工作的... - ak3nat0n
我认为不必这样做。如果你调用一个文本框的文本属性,它现在是一个相当快速的设置。如果你将处理推迟到框架中,每个调用都将受到这种惩罚的限制,即使大部分更新都来自UI线程本身。 - jasonh
@zaladane:我认为自动确定代码何时需要在UI线程上运行可能并不容易。我更喜欢语言中的一种结构(可能有点像不安全关键字),以便在UI线程上运行特定的代码块。这比使用Dispatcher代码更容易阅读。 - Yvo
@Zyphrax:我觉得确定这一点是最容易的部分。你可以调用窗体的InvokeRequired属性,如果返回值为true,就调用BeginInvoke或Invoke方法来执行需要做的操作。否则,直接调用该方法即可。 - jasonh
当然,这是基于您使用.NET Framework的前提。但是,如果.NET Framework可以像调用属性一样轻松地完成它,那么这并不难,对吧? - jasonh
@jasonh:问题在于检查是否需要调用可能很昂贵 - 如果您已经知道您在正确的线程中,您不希望每次鼠标移动等操作都发生这种情况。 - Jon Skeet

6

让整个UI线程变得安全将会非常昂贵(慢)。更好的做法是将负担放在程序员身上,在(相对较少的)情况下,当一个线程需要更新UI时进行同步。


5

这是因为UI框架是按照这种方式设计的。理论上可以设计一个真正多线程的UI框架,但很难避免死锁。

Graham Hamilton撰写了一篇关于此的好文章,并参考了主要的Java UI框架Swing。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接