Программа зависает в цикле For при обновлении метки - PullRequest
1 голос
/ 07 февраля 2011

У меня есть этот код в приложении winform:

for (int i = 1; i <= 20; i++)
 {
      lbl.Text = i.ToString();
      Thread.Sleep(100);
 }

Я ожидал, что метка будет прогрессировать с 1 до 20, но вместо этого она просто зависает во время работы цикла for, а затем отображает 20, т.е. я не вижу 1-19.

Почему это так и есть ли способ быстро обновить текст метки, как миллисекунды на аналоговых часах (я не делаю часы, просто пример.)

Спасибо

* РЕДАКТИРОВАТЬ: Это также происходит, если у меня есть кнопка с событием, которое увеличивает номер без Thread.Sleep, но у меня есть beginInvoke для воспроизведения файла wav *

Ответы [ 4 ]

4 голосов
/ 07 февраля 2011

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

Попробуйте использовать таймер с отметкой 100 мс

3 голосов
/ 07 февраля 2011

Звоните Application.DoEvents(); перед сном, который обработает все сообщения в очереди:

for (int i = 1; i <= 20; i++)
 {
      lbl.Text = i.ToString();
      Application.DoEvents();
      Thread.Sleep(100);
 }
2 голосов
/ 07 февраля 2011

Приложение зависает, и вы видите только 20 просто потому, что кажется, что оно выполняется в потоке пользовательского интерфейса, а вы Sleep его запускаете и, следовательно, блокируете цикл сообщений окна.Однако, даже если бы это было не так, вы, скорее всего, когда-либо видели бы 20, так как цикл будет выполняться так быстро.

Используйте System.Threading.Timer для выполнения каждые x миллисекунд иобновите свою метку, вызвав соответствующий метод в потоке пользовательского интерфейса.

В следующем посте показано, как реализовать то, что вам может понадобиться (хотя и в среде WPF, но принцип тот же - используйте ISynchronizeInvoke для WinFormsв отличие от Dispatcher, показанного здесь в WPF):

Обратный вызов таймера закрывает приложение WPF (DispatcherTimer работает ..)

0 голосов
/ 07 февраля 2011

Использовать таймер управления

int i=0;
     private void timer_Tick(object sender, EventArgs e)
            {
                if(i <=20)
                { 
                    lbl.Text = i.ToString(); 
                } 
             i++;
            }

Установите TimerInterval в соответствии с вашими потребностями (интервал 1000 = 1 секунда)

...