Как я могу запустить таймер сразу в форме Windows? - PullRequest
0 голосов
/ 29 мая 2018

У меня маленькая проблема.Есть что-то вроде шахматного таймера.Когда я нажимаю кнопку, текущий таймер останавливается и начинается секунда, но через 1 секунду.Как я могу начать второй сразу?here is form image

using System;
using System.Windows.Forms;

namespace WindowsFormsApp1 {
    public partial class Form1 : Form {
        byte sec1;
        byte sec2;
        public Form1() {
            InitializeComponent();
            sec1 = 0;
            sec2 = 0;
        }

        private void button1_Click(object sender , EventArgs e) {
            timer1.Start();
            timer2.Stop();
        }
        private void button2_Click(object sender , EventArgs e) {
            timer2.Start();
            timer1.Stop();
        }

        private void timer1_Tick(object sender , EventArgs e) {
            label1.Text = sec1.ToString();
            sec1++;
        }

        private void timer2_Tick(object sender , EventArgs e) {
            label2.Text = sec2.ToString();
            sec2++;
        }

    }
}

Ответы [ 2 ]

0 голосов
/ 30 мая 2018

Редактировать
Я знаю, что ваш вопрос "как запустить таймеры немедленно", но в вашем коде они запускаются немедленно.При вызове start таймер запускается.Я полагаю, что эффект, который вы видите, связан с задержкой, связанной с тиковым событием, которое, как я предполагаю, установлено в интервале 1 секунда.Поскольку вы сказали, что пытаетесь смоделировать что-то похожее на шахматный таймер (хотя в вашем случае вы будете считать, а не вниз), тогда использование чего-то вроде секундомера, который может запускать, останавливать и показывать истекшее время, было бы более подходящей моделью.,Поскольку существует класс Stopwatch, который обеспечивает именно такое поведение, я думаю, что было бы проще реализовать его с использованием двух из них и иметь только один фоновый поток, который обновляет пользовательский интерфейс так часто, как это необходимо.Вы можете даже добавить вызов обновления в каждое нажатие кнопки, чтобы обеспечить актуальность текстовых полей.

==============================

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

Тогда в ваших методах кнопок вы можете просто сделать это:

private Stopwatch sw1 = new Stopwatch();
private Stopwatch sw2 = new Stopwatch();

    private void button1_Click(object sender , EventArgs e) {
        sw1.Start();
        sw2.Stop();
    }
    private void button2_Click(object sender , EventArgs e) {
        sw2.Start();
        sw1.Stop();
    }

И затем вы можете использовать Фонового работника или какой-либо другой фоновый поток, который запускает и обновляет ваши текстовые поля с истекшим временем от таймеров, которые вам просто нужны, чтобы получить истекшее время.

// This will give you the total number of seconds elapsed.
var timer1Seconds = Math.Floor(sw1.Elapsed.TotalSeconds);

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

    private bool _stop = false;
    public Form1()
    {
        InitializeComponent();

        Task.Run(() =>
        {
            while(!_stop)
            {
                UpdateElapsedTimes();
                Thread.Sleep(1000);
            }
        }
    }

    private void UpdateElapsedTimes()
    {
        if (InvokeRequired)
        {
            Invoke(UpdateElapsedTimes());
            return;
        }

        label1.Text = Math.Floor(sw1.Elapsed.TotalSeconds).ToString();
        label2.Text = Math.Floor(sw2.Elapsed.TotalSeconds).ToString();
    }

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

0 голосов
/ 29 мая 2018

Таймер запускает немедленно.Проблема в том, что вы не сообщаете доли секунды, поэтому на дисплее будет отображаться 0 до тех пор, пока не пройдет полная секунда, что является точным с технической точки зрения.инициализируйте ваши переменные таким образом.

public Form1() {
    InitializeComponent();
    sec1 = 1;
    sec2 = 1;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...