非UI线程,UI访问

时间:2010-11-08 08:35:41

标签: c# winforms multithreading

众所周知,您无法从UI线程以外的任何其他线程更新UI。

但是,我刚刚从非UI线程中发现了一些代码,它获取了listview virtualsize的值,而没有Exception。

所以我真正的问题是: 您可以从非UI线程与UI进行哪些交互?

谢谢 西奥

2 个答案:

答案 0 :(得分:5)

因为它可以在不抛出异常的情况下工作,但并不意味着你应该这样做。

问题在于,除了对更新UI的方法的Invoke要求外,这些控件也不支持多线程。这意味着当UI线程在您检索数据时更新数据时,您确实会收到损坏的数据。

答案 1 :(得分:3)

具体规则是您无法调用使用窗口句柄的Windows API函数。使用属性或调用控件方法是否最终会进行这样的API调用并不是很明显。 MSDN文档仅列出其中4个始终可以安全使用:InvokeRequired,Invoke(),BeginInvoke()和CreateGraphics()。

但是,有时,属性值可用且不需要API调用。 Text属性就是一个很好的例子。它被缓存,因为它经常被使用。 读取 Text属性不会生成异常,只是获取缓存值。但是编写 Text属性会变成kaboom,更新屏幕上的文本需要API调用。 ListView.VirtualSize的工作方式完全相同。

你没有得到例外,但它仍然不是犹太人。毕竟,UI线程也可能稍后更改Text属性。你会得到一个陈旧的价值,一个被称为竞争条件的经典线程问题。