繁体   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