Почему эта последовательная операция не выполняется?

Я прохожу 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 ответа

Решение

Хуже того, хотя мы устанавливаем свойство Text метки до вызова ReadTheFile, цикл обработки сообщений не получает возможности обработать это изменение и обновить текст до того, как мы отправимся на обед в ReadTheFile.

В основном вы устанавливаете текст метки. Однако затем вы начинаете выполнять "интенсивную" задачу, которая может занять секунды, минуты, часы. Пока вы продолжаете загружать файл и читать количество строк, окно не будет обновляться. В этом смысл делать это в фоновом потоке. Позвольте основному потоку продолжать рисовать окно и обрабатывать пользовательский интерфейс, пока ваш фоновый поток обрабатывает файл.

Я бы продолжил учебник. Как только вы доберетесь до той части, где вы начинаете создавать и запускать фонового работника, вы можете получить один из этих "Ага!" моменты. знак равно

Вы также можете быть заинтересованы в чтении на темы в целом.

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

Вы можете прочитать метод Application.DoEvents.

Когда вы запускаете форму Windows, она создает новую форму, которая затем ожидает обработки событий. Каждый раз, когда форма обрабатывает событие, она обрабатывает весь код, связанный с этим событием. Все остальные события ждут в очереди. Пока ваш код обрабатывает событие, ваше приложение не отвечает. Например, окно не перерисовывается, если другое окно перетаскивается сверху.

Так что, пока ваш btnSelect_Click закончен, ваша форма не будет перекрашиваться.


Я бы отредактировал свой ответ, чтобы отметить, что лучше не использовать DoEvents явно, так как это может привести к довольно странному поведению программы. (по комментарию Дж. Скита).

Вы можете прочитать Использование Application.DoEvents() в SO также для получения дополнительной информации. В этой теме размещена выдержка из MSDN:

Вызов этого метода приводит к приостановке текущего потока, пока обрабатываются все сообщения окна ожидания. Если сообщение приводит к запуску события, могут выполняться другие области кода вашего приложения. Это может привести к тому, что ваше приложение будет демонстрировать неожиданное поведение, которое трудно отладить. Если вы выполняете операции или вычисления, которые занимают много времени, часто предпочтительнее выполнять эти операции в новом потоке.

Другие вопросы по тегам