Медленный таймер .
Я создаю приложение таймера для обратного отсчета и подсчета времени.
Но когда я сравниваю его с другими программами таймера, которые у меня есть, мой таймер работает медленнее.
Мое лучшее предположение заключается в том, что событие таймера содержит слишком много вещей, чтобы сделать это за 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 или в любое другое время.
Как я уже говорил, вам будет гораздо легче помочь, если вы расскажете, чего именно вы пытаетесь достичь ...