[英]Why does changing Form.Text to non-empty cause a program to display “(Not Responding)”?
我遇到過一些我不知道如何解釋的行為。 當我反復繪制到System.Windows.Forms.Form
而不小心不掛起線程時,幾秒后繪圖輸出凍結,我看到標題中的可怕(無響應)文本:
這個截圖不是中畫; 它繪制的圖像在程序結束時是完全紅色的,但是繪圖已經停止了大約一半。 奇怪的是,如果我在繪制之前跳過設置Form.Text
屬性,它就不會凍結。 誰能解釋為什么?
我使用循環來繪制一些多線程圖形填充算法的進度,但看到屏幕輸出凍結。 由於我正在繪制然后在循環中調用Thread.Sleep()
,我應該預料到這種行為( 其他帖子指出我可能應該使用BackgroundWorker
,但只是使用Application.DoEvents()
為我停止凍結)。
但是當我刪除代碼以找到我的錯誤時,真正讓我感到驚訝的是,當我刪除調用更改form.Text
,它不會再凍結了! 它並沒有要求制定者做任何事情; 分配給空字符串( form.Text = "";
)也會導致它不凍結。 所以,由於某些原因,當Text
為空時,Windows並不關心程序沒有響應,並且很樂意繼續顯示繪圖進度! 到底是怎么回事? Windows是否以不同方式處理空標題的程序?
我將代碼縮減到了查看凍結所需的最低限度。 當程序運行時,表單圖像將被循環填充為紅色。 即使循環繼續運行,大約中途填充它也會停止! 你看到它完成后它處理事件並再畫一次來顯示整個圖像是紅色的,然后再停留兩秒鍾。
(如果你運行調試(F5)它不會凍結;你必須在沒有調試的情況下運行(Ctrl-F5)。這使得所有這一切都變得更難了!)
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
// Include resources System.Drawing, System.Windows.Forms in VS before compiling
class Program
{
static void Main(string[] args) {
Bitmap image = new Bitmap(400, 20);
Form form = new Form();
form.Text = "some title"; // Comment this out to avoid the freeze
form.SetBounds(30, 30, image.Width + 16, image.Height + 38);
form.Show();
Graphics graphics = Graphics.FromHwnd(form.Handle);
for (int x = 0; x < 400; ++x)
for (int y = 0; y < 20; ++y) {
image.SetPixel(x, y, Color.Red);
graphics.DrawImage(image, 0, 0);
Thread.Sleep(1);
// Calling this would prevent the freeze:
//Application.DoEvents();
}
Application.DoEvents();
graphics.DrawImage(image, 0, 0);
Thread.Sleep(2000);
}
}
Thread.Sleep();
將阻止你的gui線程。 您的表單未更新,並且您的消息循環(處理鼠標/繪畫/鍵盤事件)被阻止。
調用Application.DoEvents將處理來自消息循環的消息,但這是一種不好的做法。 即使你沒有准備好循環,也允許關閉表單。
我認為問題是, form.Text = "some title";
向窗口發送消息(WM_PAINT)以重新繪制窗口,但永遠不會處理它。 事實證明沒有反應。 可能將Application.DoEvents
放在form.Text = "some title";
后面form.Text = "some title";
,會解決這個問題。
如果要在一段時間內更新圖形,則應該查看Timer類。 http://msdn.microsoft.com/en-us/library/system.windows.forms.timer.aspx
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.