2013-04-15 25 views
0

我知道在Windows应用程序后台线程不允许直接访问GUI项目。我不完全明白的是为什么。我发现的最接近的解释是:为什么不能从后台线程访问Windows GUI?

访问Windows窗体控件本质上不是线程安全的。如果您有两个或更多个线程操纵控件的状态,则可以强制控件进入不一致状态。其他线程相关的错误是可能的,例如竞态条件和死锁。确保以线程安全的方式访问您的控件非常重要。

这是从this MS documenation

任何人都可以详细说明两个线程可以做什么的具体示例,将窗口项放入不一致的状态吗?

+0

无论是通过API直接使用还是私下在API中共享状态(如结构)都可能很容易被搞乱。其具体内容可能因操作系统版本而异。如果有人说他们的代码不是线程安全的,我就不会冒着代码冒险,因此总是练习安全线程。 :) – WiredPrairie

回答

2

Winforms和WPF不是线程安全的,因为Windows窗口不是线程安全的。一般来说,有大量状态的大量代码从来不是线程安全的,但这样做太难了。它不限于user32和gdi32,例如浏览器不是线程安全的。即使微软为了使窗口线程安全而经历了非常长的时间,它在实践中仍然不能很好地工作。因为这不会自动使您的代码线程安全。如果线程不协调以确定窗口应该是什么样子的话,那么你仍然会对抗毛刺。一个很难解决的问题,我有伤痕来证明它。通用的解决方案是只让一个线程负责其内容。

在Windows中,只有kernel32是线程安全的。必然如此,如果情况并非如此,你将无法安全地使用线程。你可以在kernel32 api函数中看到它,它们做的事情非常小,影响很小的状态。

+2

其实,Windows是线程安全的。 (例如,您可以从任何线程调用GetWindowText)。问题是编写使用Windows的代码的人很少编写线程安全的代码。线程安全性很难。您从一个线程更新值,但由于缓存一致性问题,该值直到一段时间后才会变为对其他线程可见。或者您从一个线程读取值,并且在您仍在使用该值时,另一个线程使其无效。这些错误会让人们疯狂。标准的解决方案是说:“不要那样做,别尝试,你会发疯的。” –