为何进度更新在理论上阻塞UI线程?
在简单的应用程序我有一个进度条和标签。我运行一个耗时的方法在UI线程,试图更新进度和标签。这是的没有的应该是工作,因为阻塞UI线程。但进度正在更新!
直到我做的表格上任何东西,它冻结的进度更新(标签不)。
这是为什么?
例如code(放一个按钮,进度和形式的标签):
私人无效的button1_Click(对象发件人,EventArgs的) { 而(真) { progressBar1.Value + = 1; label1.Text + =1; Thread.sleep代码(100); } }
进度正在更新,标签是没有的。我的问题的不是的如何使标签更新藏汉,但为什么进度的是的更新。我知道有关线程,的DoEvents,异步/计谋,而不是问题的答案。
解决方案我觉得这是很难完全回答这个问题,无需拆卸一个位的Windows,这是太辛苦了,我现在的。
不过基本上,当你一个的WinForms进度控制上设置.value的,但它确实比调用SendMessage函数与消息1026(PBM_SETPOS),它告诉Windows进度条来设置它的位置而已。
我会得出这样的结论Windows进度条同步重绘自己响应PBM_SETPOS的以及的响应WM_PAINT。也许它的运行上,才能做花哨的眩光动画另一个线程的计时器,这是能够重新绘制控件,而不必等待绘制消息。
无论哪种方式,它只是Windows内部,你所看到的 - 和绘画的东西WM_PAINT处理之外没有的是的一个不寻常的技术,尽管它不是做事情的教科书的方式
其实,在看文档的PBM_SETPOS( msdn.microsoft/en-us/library/bb760844(v=vs.85).aspx )它的记录为导致重绘 - 我想这样做是故意帮懒人/无经验得到阻断进度条更新,而不适当做所有常用的麻烦工作。
Why does the ProgressBar update in theoretically blocked UI thread?
In simple app I have a ProgressBar and a Label. I run a time-consuming method in UI thread which tries to update the ProgressBar and the label. This is not supposed to work, because of blocked UI thread. But the ProgressBar is updating!
Until I do anything on the form and it freezes, the ProgressBar updates (the label does not).
Why is that?
Example code (put a Button, a ProgressBar and a Label on form):
private void button1_Click(object sender, EventArgs e) { while (true) { progressBar1.Value += 1; label1.Text += "1"; Thread.Sleep(100); } }ProgressBar is updating, Label is not. My question is not how to make label update aswell, but why ProgressBar is updating. I DO know about Threads, DoEvents, async/await and that is not the answer.
解决方案I think it's hard to answer this completely without disassembling a bit of Windows, which is too much work for me right now.
But basically, when you set .Value on an WinForms ProgressBar control, it does little more than call SendMessage with message 1026 (PBM_SETPOS), which tells the Windows progress bar to set its position.
I would conclude that the Windows progress bar redraws itself synchronously in response to PBM_SETPOS as well as in response to WM_PAINT. Or perhaps it's running a timer on another thread in order to do the fancy glare animation, and that's able to redraw the control without waiting for a paint message.
Either way, it's just Windows internals you're seeing - and drawing stuff outside WM_PAINT handlers is not that an unusual technique, even though it's not the textbook way of doing things.
Actually, looking at the docs for PBM_SETPOS ( msdn.microsoft/en-us/library/bb760844(v=vs.85).aspx ) it's documented as causing a redraw - I guess this is done deliberately to help the lazy/inexperienced to get blocking progress bar updates to work without all usual hassle of doing it properly.
更多推荐
在阻塞UI线程进度更新
发布评论