我遇到過一些我不知道如何解釋的行爲。當我反覆畫上System.Windows.Forms.Form
不小心不要掛線,幾秒鐘後,繪圖輸出會被凍結,我看到了可怕的(無響應)文本標題: 爲什麼將Form.Text更改爲非空會導致程序顯示「(Not Responding)」?
這張截圖是不是中期平局;在程序結束時,它正在繪製的圖像是完全紅色的,但繪圖已經停止了大約一半。 奇怪的是,如果我在繪圖之前跳過設置Form.Text
屬性,它不會凍結。有人可以解釋爲什麼嗎?
我正在使用循環來繪製一些多線程圖形填充算法的進度,但看到屏幕輸出凍結。因爲我正在繪製,然後在循環中調用Thread.Sleep()
,所以我應該預料到這種行爲(other posts指出我可能本應該使用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);
}
}
由於無響應的用戶界面,表單凍結。這沒有什麼可以形成標題 –
我明白,使用戶界面不響應會導致它凍結。但是如果我將標題留空,它不會凍結。運行代碼不會給你這種行爲嗎? –
沒有。至少在Windows 7上 –