簡體   English   中英

為什么將Form.Text更改為非空會導致程序顯示“(無響應)”?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM