我们知道,除了实例化元素的线程之外,不可能从任何线程执行操作任何UI元素属性的代码……我的问题是:为什么?
我记得当我们使用COM用户界面元素时(在COM/Visual basic6.0时代),所有的UI元素都是使用COM类和co类创建的,这些类使用称为线程本地存储(TLS)的内存模型来存储它们的资源,但我记得,这是必需的,因为COM组件的构造方式有关,不应该与.NET UI元素相关。这个限制仍然存在的潜在原因是什么?
是否因为底层操作系统仍然对所有UI元素使用基于COM的Win32 API类,即使是在托管.NET应用程序中操作的UI元素?
发布于 2010-06-02 07:55:30
AFAIK,它甚至比COM更基础。它直接指向好的老Windows API。我相信windows中的窗口应该由一个线程拥有,句号。每个线程都有自己的消息泵,将消息分派到它所拥有的窗口。它是Windows的一个非常基本的构造--现在可能有点过时,但却是基本的。
我的感觉是,当您需要将WPF集成到Windows窗体应用程序中时,或者当您需要使用在某个地方获得的HWND在应用程序中的其他位置摆弄Windows对象时,这种线程亲和性有助于实现互操作性。这可能也是允许旧版本的Windows (XP)在不对操作系统本身进行任何重大体系结构更改的情况下托管WPF应用程序的原因。
发布于 2010-06-02 08:13:21
听起来您指的是WPF,而不是通用的Windows API编程。我不是WPF内部的专家,但这里有一些关于为什么将UI操作放在一个UI线程中是一个好主意的原因:
最后一项是与Win API相关的。创建窗口句柄时,它将绑定到发出CreateWindow调用的线程。发送到该窗口句柄的消息将被放入与该线程关联的消息队列中。如果该线程不处理窗口消息,则该窗口将被非响应式UI冻结。如果另一个线程尝试SendMessage到该窗口,该线程也将被冻结,等待同步调用完成。这场雪球很快就变得丑陋起来。这就是为什么要确保只在准备处理窗口消息的线程上创建窗口句柄的原因。
为什么窗口句柄的消息队列被绑定到特定的线程?我不知道,但我确信答案不是微不足道的。
发布于 2010-06-02 08:09:26
来自http://msdn.microsoft.com/en-us/library/ms741870.aspx:
以前,Windows只允许UI元素由创建它们的线程访问。这意味着负责某个长时间运行的任务的后台线程无法在文本框完成时更新该文本框。Windows这样做是为了确保UI组件的完整性。如果列表框的内容在绘制过程中被后台线程更新,则该列表框可能看起来很奇怪。
https://stackoverflow.com/questions/2954139
复制相似问题