0

我正在this tutorial讨论如何在后台执行一些工作,在这段代码中,我对为什么在调用方法reading the file...之前不显示消息感到困惑。ReadTheFile(filename)

private void btnSelect_Click(object sender, EventArgs e)
{
    OpenFileDialog ofd = new OpenFileDialog();
    ofd.CheckFileExists = true;
    ofd.CheckPathExists = true;

    if (ofd.ShowDialog() == DialogResult.OK)
    {
        lblResults.Text = " ... reading the file ...";
        FileReader1 fr = new FileReader1();
        int numLines = fr.ReadTheFile(ofd.FileName);

        lblResults.Text = string.Format("We read {0} lines", numLines.ToString());
    }
}

作者通过以下方式解释它,但它并没有真正让我明白。

Worse, even though we set the label’s Text property before we call ReadTheFile, the message loop doesn’t get a chance to process that change, and update the text, before we go out to lunch in ReadTheFile.

这是什么意思?这可以用更简单的术语来解释吗?

4

2 回答 2

2

更糟糕的是,即使我们在调用 ReadTheFile 之前设置了标签的 Text 属性,消息循环也没有机会在我们去 ReadTheFile 吃午饭之前处理该更改并更新文本。

基本上你正在设置标签的文本。但是,您随后开始执行可能需要几秒钟、几分钟、几小时的“密集”任务。只要您继续加载文件并读取行数,窗口就不会更新。这就是在后台线程中执行此操作的重点。在后台线程处理文件时,让主线程继续绘制窗口并处理 UI 内容。

我将继续本教程。一旦你开始创建和运行后台工作程序的部分,你最终可能会得到其中一个“啊哈!” 时刻。=)

您可能也有兴趣阅读一般的线程。

http://www.codeproject.com/Articles/26148/Beginners-Guide-to-Threading-in-NET-Part-1-of-n

http://www.techrepublic.com/article/a-beginners-guide-to-threading-in-c/1044970

于 2012-11-22T06:45:51.897 回答
1

您可以阅读Application.DoEvents Method

当您运行 Windows 窗体时,它会创建新窗体,然后等待事件处理。每次表单处理一个事件时,它都会处理与该事件相关的所有代码。所有其他事件都在队列中等待。当您的代码处理事件时,您的应用程序不会响应。例如,如果将另一个窗口拖到顶部,则该窗口不会重新绘制。

因此,在您btnSelect_Click完成之前,您的表单不会重新绘制。


我会编辑我的回答来评论,最好不要DoEvents明确使用,因为它可能会导致相当奇怪的程序行为。(基于 J.Skeet 的评论)。

您也可以在 SO 上阅读Use of Application.DoEvents() 以获取更多信息。该线程中发布了来自 MSDN 的摘录:

调用此方法会导致当前线程暂停,同时处理所有等待窗口消息。如果消息导致事件被触发,那么您的应用程序代码的其他区域可能会执行。这可能会导致您的应用程序出现难以调试的意外行为。如果您执行需要很长时间的操作或计算,通常最好在新线程上执行这些操作。

于 2012-11-22T06:51:15.317 回答