【问题标题】:Why can't you access Windows GUI from a background thread?为什么不能从后台线程访问 Windows GUI?
【发布时间】:2013-04-16 03:10:52
【问题描述】:

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

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

来自this MS documenation

谁能详细说明两个线程可以做什么会使窗口项进入不一致状态的具体示例?

【问题讨论】:

  • 任何存在共享状态(如结构)的东西,无论是直接通过 API 使用,还是在 API 中私下使用,都可能很容易被搞砸。其细节可能因操作系统版本而异。如果有人说他们的代码不是线程安全的,我永远不会用我的代码冒险,因此总是练习安全线程。 :)

标签: windows multithreading thread-safety


【解决方案1】:

Winforms 和 WPF 不是线程安全的,因为 Windows 窗口不是线程安全的。通常,具有大量状态的大量代码永远不是线程安全的,要做到这一点太难了。它不仅限于 user32 和 gdi32,例如浏览器也不是线程安全的。即使微软竭尽全力使 Windows 线程安全,它在实践中仍然不能很好地工作。因为这不会自动使您的代码线程安全。如果线程不协调以确定窗口的外观,您仍然会遇到故障。一个很难解决的问题,我有伤疤来证明它。通用的解决方案是只让一个线程负责其内容。

在 Windows 中,只有 kernel32 是线程安全的。必然如此,如果不是这种情况,您将无法安全地使用线程。你在 kernel32 api 函数中看到了这一点,它们做的事情非常小,影响非常小。

【讨论】:

  • 实际上,windows 是线程安全的。 (例如,您可以从任何线程调用GetWindowText。)问题是使用windows 编写代码的人很少编写线程安全代码。线程安全很难。您从一个线程更新一个值,但由于缓存一致性问题,该值直到一段时间后才会对另一个线程可见。或者您从一个线程读取一个值,当您仍在使用该值时,另一个线程使其无效。这些类型的错误使人们发疯。标准解决方案是说“不要那样做。甚至不要尝试。你会发疯的。”
猜你喜欢
  • 1970-01-01
  • 2016-09-13
  • 1970-01-01
  • 2012-06-26
  • 1970-01-01
  • 1970-01-01
  • 2011-08-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多