为什么这个顺序操作没有被执行?

时间:2012-11-22 06:23:53

标签: c# backgroundworker

我正在通过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.

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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

您可以阅读Application.DoEvents Method

  

运行Windows窗体时,它会创建新窗体,然后等待   要处理的事件。每次表单处理一个事件时,它   处理与该事件相关的所有代码。所有其他活动   排队等候。当您的代码处理事件时,您的应用程序   没有回应。例如,窗口不会重新绘制另一个窗口   窗口被拖到顶部。

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


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

您还可以阅读Use of Application.DoEvents() at SO了解更多信息。在该主题中发布了MSDN的摘录:

  

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