为什么ProgressBar会在理论上阻塞的UI线程中更新?
在简单的应用程序中,我有一个进度栏和一个标签。我在 UI 线程中运行一个耗时的方法,尝试更新 ProgressBar 和标签。这是not应该可以工作,因为 UI 线程被阻塞。但进度条正在更新!
直到我在表单上执行任何操作并且它冻结之前,ProgressBar 都会更新(标签不会更新)。
这是为什么?
示例代码(在表单上放置一个按钮、一个进度条和一个标签):
private void button1_Click(object sender, EventArgs e)
{
while (true)
{
progressBar1.Value += 1;
label1.Text += "1";
Thread.Sleep(100);
}
}
ProgressBar 正在更新,Label 没有更新。我的问题is not如何进行标签更新以及为什么 ProgressBaris更新。我确实了解线程、DoEvents、async/await,但这不是答案。
我认为如果不拆卸一些 Windows 就很难完全回答这个问题,这对我来说现在的工作量太大了。
但基本上,当您在 WinForms ProgressBar 控件上设置 .Value 时,它所做的只不过是使用消息 1026 (PBM_SETPOS) 调用 SendMessage,该消息告诉 Windows 进度栏设置其位置。
我得出的结论是,Windows 进度条会同步重绘自身以响应 PBM_SETPOS也响应 WM_PAINT。或者,它可能在另一个线程上运行计时器,以便执行精美的眩光动画,并且能够重绘控件,而无需等待绘制消息。
无论哪种方式,您所看到的只是 Windows 内部结构 - 而在 WM_PAINT 处理程序之外绘制内容则不是that这是一种不寻常的技术,尽管它不是教科书上做事的方式。
实际上,查看 PBM_SETPOS 的文档(http://msdn.microsoft.com/en-us/library/bb760844(v=vs.85).aspx)它被记录为导致重绘 - 我想这是故意这样做的,以帮助懒惰/缺乏经验的人让阻塞进度条更新正常工作,而无需正确执行所有通常的麻烦。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)