2012-09-13 5 views
3

Это мой код:Могу ли я использовать таймер, чтобы обновить метку каждые х милисекунд

Stopwatch timer = new Stopwatch(); 
timer.Start(); 
while (timer.ElapsedMilliseconds < 3000) { 
    label1.Text = Convert.ToString(timer.ElapsedMilliseconds); 
} 
timer.Stop(); 

Мой intetion был обновить текст лейбла в режиме реального времени, так что если timer.ElapsedMilliseconds == 1350, то label1.Text = 1350. Как я могу это сделать? Заранее спасибо!

+1

В чем проблема? (Обратите внимание, что это приведет к высокому использованию ЦП) –

+0

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

+0

Я поместил этот код в 'mainWindow() {}'. Но форма начинается после того, как таймер находится в 3000 миллисекунд, поэтому форма начинается после остановки таймера. –

ответ

5

Вы не можете обновить интерфейс в таком замкнутом цикле, потому что, пока поток пользовательского интерфейса работает с этим кодом, он не отвечает на события рисования. Вы можете делать такие неприятные вещи, как «DoEvents()», но, пожалуйста, не ... было бы лучше просто иметь Timer и периодически обновлять интерфейс, когда срабатывает событие таймера; каждые 50 мс было бы самым быстрым, я бы пошел лично.

9

Лучше использовать System.Windows.Forms.Timer для этого, а не Stopwatch()

Даже если таймер менее точен, то StopWatch(..) это дает хороший контроль.

Просто пример sniplet:

myTimer.Tick += new EventHandler(TimerEventProcessor);  
    myTimer.Interval = 1350; 
    myTimer.Start(); 

    private void TimerEventProcessor(...){   
    label1.Text = "..."; 
    } 
+1

хотя, я думаю, ему нужно будет проверить 'InvokeRequired' перед тем, как сделать' label1.Text = ..', правильно ..? – Default

+0

@Default: нет, в случае Windows.Forms.Timer вам это не нужно, он работает в потоке пользовательского интерфейса. System.Timer.Timer работает в другом потоке, поэтому * там * да, вам нужно управлять Invoke stuff. – Tigran

1

Является ли это приложение WinForms?

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

Вы можете добавить быстрое и "грязное" решение здесь (если WinForms). Измените свою петлю следующим образом:

while (timer.ElapsedMilliseconds < 3000) { 
    label1.Text = Convert.ToString(timer.ElapsedMilliseconds); 
    Application.DoEvents(); 
} 

Теперь метка должна обновляться между циклами.

+0

Ваш метод работает! Спасибо! –

+0

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

+0

Конечно, это просто для обучения.Я нашел все о 'System.Windows.Forms.Timer' –

1

Если вы хотите обновить каждый второй можно использовать оператор модуля в вашем while цикла:

Stopwatch timer = new Stopwatch(); 

timer.Start(); 

while (timer.ElapsedMilliseconds < 3000) { 
    if (timer.ElapsedMilliseconds % 1000 == 0) 
    { 
     label1.Text = timer.ElapsedMilliseconds.ToString(); 
    } 
} 

timer.Stop(); 

Оператор модуля дает остаток от операции деления, если миллисекунды кратны 1000 он будет return 0.

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