首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

在用户界面线程上等待的危险性

我们做这么一个假设哈。

如果有一个线程,它拥有一个窗口,则在这个线程的整个运行过程中,我们都不应该调用 Sleep 函数。为什么?

因为 Sleep 调用会导致线程在睡眠等待期停止处理窗口消息。即使对于持续时间较短的睡眠也是如此,例如睡眠几秒钟和醒来以轮询系统中某些内容的状态。

如我之前在另一篇文章中所提到的,轮询会降低系统性能,还会损害系统在低功耗情况下节省能源的能力,并受到终端服务器的放大效应的影响。

如果当前处理器处于空闲状态,那就继续保持闲着。如果处理器很忙,那就赶紧让它完成计算任务,然后重新回到空闲状态。

但有时候我还是会看到如下的代码:

请注意,此消息循环长达两秒钟而不处理消息。人们通常不会将两秒钟的睡眠插入负责与最终用户交互的线程中,但他们经常为后台工作线程执行此操作,这些线程为跨线程通信目的创建了隐藏窗口。由于线程没有可见的 UI,因此将最终用户一次挂起几秒钟是不会有明显的感知的。

但是,存在某些特殊情况。

如果系统需要广播消息,则必须等待此休眠线程最终唤醒并处理广播消息。同时,发出广播的组件继续等待。例如,用户可能双击了需要 DDE 才能打开的文档。DDE 过程从广播 WM_DDE_INITIATE 消息开始,该消息停滞在窗口后面。你的无响应隐藏窗口刚刚创建了一个 “Windows 似乎以随机间隔挂起几秒钟” 错误。

请注意,许多人忽略了调用 CoInitialize(可能间接)来初始化 STA 的线程会创建一个隐藏窗口以执行列集。因此,在单线程单元中运行的线程必须不停地处理消息。如果不这样做,由于窗口无响应,将导致神秘的系统级卡顿。

总结

对于在用户界面线程中执行的代码,我的观点是:不是非常必要,都不要使用 Sleep。

人的生命是有限的,软件运行的快,是一个终极需求。

最后

Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一,里面有很多关于Windows的小知识,对于广大Windows平台开发者来说,确实十分有帮助。

本文来自:《The dangers of sleeping on a UI thread》

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20230619A02MD000?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券