Таймер Winforms для чайников

Я пытаюсь установить таймер один раз в секунду в winform, когда я ищу совет, как это сделать, я нахожу массу вещей о потоках. Ну, я не забочусь о потоках, потому что все, что я пытаюсь сделать, это сделать отсчет значения с 60 до 0 за одну минуту, а затем остановиться. Я не думаю, что нам нужно пойти в облачные вычисления, чтобы решить эту проблему, но я действительно являюсь веб-формами, поэтому я немного ржавый по этой проблеме. Может ли кто-нибудь указать мне пример

Вот что я пробовал

private void button1_Click(object sender, EventArgs e)
    {
        this.timeLeft = 60;
        this.label1.Visible = false;
        this.button1.Visible = false;
        gt = new Timer();
        gt.Tick += new EventHandler(CountDown);
        gt.Interval = 1000;
        gt.Start();
    }

private void CountDown(object sender, EventArgs e)
{
    do
    {
        this.TimeBar.Value = timeLeft;                
        this.timeLeft -= 1;
    } while (this.timeLeft > 0);
    if (this.TimeBar.Value > 0) return;
    gt.Stop();
    this.label1.Visible = true;
    this.button1.Visible = true;
}

Любая помощь будет оценена.

Ответы

Ответ 1

Что происходит, вы уменьшаете переменную timeLeft до тех пор, пока она не достигнет нуля при первом тике таймера. Выньте цикл do...while, и у вас будет в основном рабочий пример.

Однако, если вы собираетесь выполнять любую работу Windows Forms, вам нужно узнать о потоковой передаче и о том, как это влияет на пользовательский интерфейс. Вы очень быстро окажетесь здесь, если не будете рассказывать о бесполезных исключениях и неправильном использовании компонентов пользовательского интерфейса. У Jon Skeet есть отличная сериал . Я очень рекомендую. В нем есть раздел, посвященный таймерам, который может дать вам дополнительную информацию.

Ответ 2

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

Отбросьте элемент управления таймера на своей странице, назовите его "таймер" и вставьте следующий код:

public MainForm()
{
    InitializeComponent();

    timer.Interval = 1000;
    timer.Start();

    timeLeft = 60;
    timer.Tick += Timer_Tick;

    // start things
    label1.Hide();
    button1.Hide();
    timer.Start();

}

public void Timer_Tick(object sender, EventArgs e)
{
    timeLeft--;

    if (timeLeft <= 0) {
        timer.Stop();
        label1.Show();
        button1.Show();
    }
}

Я полагаю, что если вы пришли с веб-фона, программирование, управляемое событиями, вероятно, это то, что вам нужно, чтобы начать чтение, если вы хотите понять, как программируются вещи на рабочих столах.

Ответ 3

Помимо вынимания цикла (согласно jasonh answer), ваш подход может стать немного неточным, если приложение занято. Хотя вы указываете свой интервал в миллисекундах, таймеры WinForms имеют разрешение 18 мс и имеют очень низкий приоритет, цикл сообщений проверяет только таймеры, если он не находит ничего другого.

Итак, сохраните значение StartTime (DateTime) и используйте это, чтобы вычислить оставшееся время в каждом событии Timer. Вам может понадобиться 61 тик, чтобы добраться до минуты.

Ответ 4

Вы не хотите делать никаких циклов в обработчике событий. Обработчик вызывается один раз на таймер "tick" - каждые 1000 миллисекунд, как вы его настроили. Таким образом, вы хотите уменьшить вашу переменную timeLeft один раз за вызов, а затем закрыть все это, когда timeLeft достигнет нуля.

// untested
private void CountDown(object sender, EventArgs e)
{
    this.TimeBar.Value = timeLeft;
    this.timeLeft--;
    if (this.TimeBar.Value == 0)
    {
        gt.Stop();
        this.label1.Visible = true;
        this.button1.Visible = true;
    }
}