_Q12_ Ответов: 4

Медленный таймер .


Я создаю приложение таймера для обратного отсчета и подсчета времени.
Но когда я сравниваю его с другими программами таймера, которые у меня есть, мой таймер работает медленнее.
Мое лучшее предположение заключается в том, что событие таймера содержит слишком много вещей, чтобы сделать это за 1 секунду. Слишком много "если".
один)-Я думаю, что лучший подход к этому вопросу - просто сделать это:
int h1 = 0,h2 = 0;
int m1 = 0;m2 = 0
int s1 = 0;s2 = 0;
private void timer1_Tick(object sender, EventArgs e)
{
  h1--;m1--;s1--;
  h2++;m2++;s2++;  //and that's it
}

а затем каким-то образом обновите форму 1, но не вмешиваясь в событие таймера.
б)-Одна идея состоит в том, чтобы создать еще один таймер (timer2), и в этом тиковом событии обновить форму 1...но я беспокоюсь, если timer2 замедлит timer1?
с)-Еще одна идея состоит в том, чтобы сделать два(2) потока для запуска декремента в одном потоке и обновления пользовательского интерфейса в другом потоке.
д)- Еще одна идея состоит в том, чтобы "нарисовать" пользовательский интерфейс после того, как таймер выполнит минимальную рутину. Я могу легко сделать так, чтобы bool стал ложным, когда происходит ТИК, и в событии "Paint" выполнить все декрементирование и все if и установить этот bool в true. Для этого я должен сделать событие для bool, и это выше моих ушей...
Я надеюсь, что это простое решение этой проблемы, и прежде чем перейти к коду, я думаю, что лучше сначала спросить и получить некоторые мнения.
Спасибо!

Что я уже пробовал:

Мой оригинальный код здесь:
int h = 0;
int m = 0;
int s = 0;
private void timer1_Tick(object sender, EventArgs e)
{
    if (isTickActive) Ticking();

    if (isTimer)
    {
        s = s - 1;
        if (s == -1)
        {
            m = m - 1;
            s = 59;
        }
        if (m == -1)
        {
            h = h - 1;
            m = 59;
        }
        if (h == -1)
        {
            h = m = s = 0;
        }
        if (h == 0 && m == 0 && s == 0)
        {
            timer1.Stop();
            button1.Text = "Start";
            labelinfo.Text = "finished";
            Ledstop = true; LedColor();

            if (isAlarmActive) SoundTheAlarm();
        }
    }
    else //isClock
    {
        s = s + 1;
        if (s == 60)
        {
            m = m + 1;
            s = 0;
        }
        if (m == 60)
        {
            h = h + 1;
            m = 0;
        }
        if (h == 24)
        {
            h = m = s = 0;
            timer1.Stop();
            button1.Text = "Start";
            labelinfo.Text = "finished";
            Ledstop = true; LedColor();
        }
    }

    label1.Text = s + "";
    label2.Text = m + "";
    label3.Text = h + "";
    if (s < 10) label1.Text = "0" + s;
    if (m < 10) label2.Text = "0" + m;
    if (h < 10) label3.Text = "0" + h;
}

Ralf Meier

Я бы не стал так работать, потому что это вызовет большое временное дрожание (как вы описали выше).
Почему бы вам не работать с такими системными частями, как (например) Система.Значение datetime.Сейчас ?

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

_Q12_

спасибо за ваш ответ!
Все, что мне нужно, - это настраиваемое приложение таймера, и это было мое первое приложение таймера в моей жизни - и оно работает так, как я хотел (за исключением задержки). Ваше предложение состоит в том, чтобы сделать еще один код вокруг класса Datetime? Я не думал об этом, когда начинал... ну, может быть, на секунду, но я выбираю то, что уже закодировал. Это интересная идея. Я подумаю об этом.

Ralf Meier

Что вообще следует знать о событиях, так это :
Возможно, событие возникает/срабатывает в нужный момент - но приложение работает с ним, когда для этого есть время - в худшем случае это может быть секундой (а может быть, и минутой) позже.
Поэтому, конечно, вы могли бы создать свое собственное приложение-таймер (? Task-scheduler ?) но вот что я предлагаю: при первом же его вызове запомните метку времени сейчас, а в последующем работайте с результирующим промежутком времени между моментом сейчас и этой запомнившейся меткой времени ...

_Q12_

ААА... может быть, псевдокод поможет? Я не понял вашего объяснения. Извиняюсь.

Ralf Meier

Да, псевдокод помог бы ...
Но опять же : какова конечная цель ? Я думаю, что мог бы быть гораздо более конкретным, если бы Вы тоже были более конкретными ...

_Q12_

цель программного обеспечения состоит в том, чтобы пользователь установил время в сек/мин/часах, и при нажатии кнопки начинается обратный отсчет, пока он не достигнет 0ч/0м/0С и не остановится. Он работает в секунду. С каждой секундой отсчет уменьшается на 1. Если у меня есть набор 9s, в следующую секунду он станет 8s, и так далее, пока не достигнет 0s.

RickZeeland

Используете ли вы элемент управления таймером в своей форме из панели инструментов ? Я столкнулся с большим количеством проблем с этим, я бы рекомендовал использовать таймер из системы.Вместо таймеров.

Ralf Meier

Я с вами не согласен.
Единственное отличие заключается в том, что компонент Timer-Component из Toolbox инстанцируется на форме (и принадлежит ей).
Методы и принцип работы одинаковы (если это на самом деле не один и тот же объект).

_Q12_

Это должно быть то же самое, что я согласен, но я сделаю тест, так как его очень легко изменить.

_Q12_

Да, я добавил таймер в дизайнере. (Не из кода.)
Вы рекомендуете создать объект таймера в коде?
Это безболезненно - я могу сделать это очень быстро.
Я сообщу вам о производительности после того, как перепишу код и проведу несколько тестов.

_Q12_

Я снова запускаю тест с объектом таймера, сделанным из кода.
Результат тот же, что и раньше.

Richard MacCutchan

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

_Q12_

Точно так же и моя мысль. Спасибо, мистер Ричард.
Но как это осуществить? Я описал нечто подобное в пункте В), но я слишком много думаю об этом там. Твои мысли?
Я уже сделал тест с 2 таймерами, и он все еще остается позади.

частный недействительными timer1_Tick(объект отправителя, EventArgs в электронной)
{
если (истимер)
{
s = s - 1;
}
else / / isClock
{
s = s + 1;
}

}
и timer2 делает то же самое, что и исходный код + некоторые незначительные детали для работы обоих таймеров.

Richard MacCutchan

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

private void timer1_Tick(object sender, EventArgs e)
{
DateTime dt = DateTime.Now; // the actual current time
}

Если вам нужно сделать больше обработки на мероприятии, то вы должны остановить таймер во время выполнения другой работы, а затем перезапустить его, когда закончите. Видеть https://msdn.microsoft.com/en-us/library/system.windows.forms.timer.tick(v=против 110). aspx для примера кода.

_Q12_

Моя проблема заключается в преобразовании и обновлении после того, как тик прошел. Как/где проводить эти операции?

Richard MacCutchan

Преобразование или обновление чего? У вас есть вся необходимая информация из объекта DateTime, все, что вам нужно сделать, это отобразить ее. В документации показано, какие различные варианты доступны.

_Q12_

Но как преобразовать нормальное время из объекта DateTime в время обратного отсчета? Когда нормальное время от объекта DateTime равно 1m05s, mytimer должен каким-то образом уменьшить это значение. Только с моими собственными счетчиками это возможно. Я просматриваю страницу, которую вы опубликовали, и не вижу решения моей проблемы... не могли бы вы указать мне на нее?
-- переиздано--
в вашем примере microsoft они также используют пользовательский счетчик: [ alarmCounter +=1;] внутри события timer tick с именем TimerEventProcessor. Это именно то,что я уже сделал, но для 3 переменных.

Graeme_Grant

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

_Q12_

Спасибо (Graeme_Grant)!
Очень Интересно!
Но Как?
вот быстрый псевдокод:

textBox1_TextChanged
{
ы = датавремя.с
запрос =6;
пересчитывать();
}
s = 0; / / s = datetime.s в TextChanged
конец=0;
запрос =6;
пустота пересчитать()
{
end=s-запрос;
}
частный недействительными timer1_Tick(объект отправителя, EventArgs в электронной)
{
с--;
Если (s= end)
{
таймер.стоп
}

}

Richard MacCutchan

Ты все еще не понимаешь. Счетчик в этом примере не имеет ничего общего с фактической разницей во времени.

Используйте объект DateTime, как я уже говорил. Если вам нужно время, прошедшее между тиками, то просто сохраните время, когда таймер запускается, и вычтите его из текущего времени на каждом ТИКе. Используйте объект TimeSpan для разности, которую затем можно использовать для простого извлечения количества прошедших часов, минут и секунд.

_Q12_

Теперь я понимаю. Я должен экспериментировать с этими новыми подходами. Большое спасибо.

Ralf Meier

Я где - то несколько часов отсутствовал-интересно, куда тем временем делась эта "дискуссия"...
Для вашего понимания :
Таймер может быть использован для циклических операций, где на самом деле нет необходимости держать точный интервал.
Одним из примеров может быть: пусть метка мигает ...
Или отправить текст через SerialPort или TCP ...
Вы также можете использовать его для своего рода планировщика задач, если вы хотите выполнить действие, возможно, после 7 часов, но не если вы хотите сделать это точно в 7:00:00 или в любое другое время.

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

4 Ответов

Рейтинг:
1

Patrice T

Этот код просто неправильный:

int h1 = 0,h2 = 0;
int m1 = 0;m2 = 0
int s1 = 0;s2 = 0;
private void timer1_Tick(object sender, EventArgs e)
{
  h1--;m1--;s1--;
  h2++;m2++;s2++;  //and that's it
}

Почему бы вам не использовать RTC (часы реального времени) ?
Когда вы начинаете считать
start= DateTime.Now;

Когда вы хотите знать прошедшее время
now= DateTime.Now;
elapsed= now.Subtract(start); // in seconds

установите таймер только для обновления дисплея или что вам нужно ?
Функции библиотеки C времени()[^]
значение datetime.Теперь Собственность (Система)[^]
значение datetime.Метод Вычитания (DateTime) (System)[^]


_Q12_

Я думаю, что ваша функция времени предназначена для c/c++.
Это c#. Я не настолько продвинут (или умен), чтобы красть из c++ и адаптироваться к c#. Вероятно, это очень хорошая идея, но в данном случае проблема заключается во мне. :) В любом случае спасибо.

Patrice T

ой
Я был абсолютно уверен насчет С.

Patrice T

Сейчас должно быть лучше.

Richard MacCutchan

В C#?

_Q12_

ихи

Patrice T

ой
Я был абсолютно уверен насчет С.

Рейтинг:
1

Graeme_Grant

Поиск Google выплевывает тонны примеров... Здесь: Создание простого приложения секундомера / таймера с помощью C# / Windows Forms[^]


Рейтинг:
0

Richard MacCutchan

Видеть Структура DateTime (Система)[^], Структура Временного Интервала (Система)[^] и Секундомер Класса (Система.Диагностика)[^].

Все вышеперечисленное можно использовать для достижения желаемого.


_Q12_

Спасибо! Я должен экспериментировать с ними.

Рейтинг:
0

_Q12_

Я повторю свой предварительный ответ вам здесь:
вы сказали:
"Сохраните дату и время, когда таймер запускается, и вычтите прошедшее время... Это есть в документации ... кроме того, google it и есть десятки примеров того, как это сделать...
"
моя реакция:

Спасибо (Graeme_Grant)!
Очень Интересно!
Но Как?
вот быстрый псевдокод:

textBox1_TextChanged
{
ы = датавремя.с
запрос =6;
пересчитывать();
}
s = 0; / / s = datetime.s в TextChanged
конец=0;
запрос =6;
пустота пересчитать()
{
end=s-запрос;
}
частный недействительными timer1_Tick(объект отправителя, EventArgs в электронной)
{
с--;
Если (s= end)
{
таймер.стоп
}

}

Теперь я просматриваю образцы из вашей ссылки.
Я уже нахожу что-то интересное, чего не знал:
DateTime endTime = new DateTime(2013,01,01,0,0,0);
TimeSpan ts = конечное время.Вычитать(Типа Datetime.Сейчас); //?!^!#@!
Мне придется испытать эти новые методы и подходы.