Таймеры .NET: как лучше всего получать уведомления за X секунд?

Предположим, у меня есть одноразовое событие, которое нужно поднять через X секунд, например тайм-аут. Интуитивно было бы разумно создать System.Timers.Timer, установить для него интервал X * 1000, связать его галочку с событием и запустить его. Поскольку это единовременное событие, и вы хотите, чтобы оно возникло только один раз, вам придется останавливать таймер после того, как он сработает.

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

Может ли кто-нибудь взвесить, какой из этих методов лучше (возможно, есть еще один вариант, о котором я тоже не думал). Становится ли один метод лучше другого, если время ожидания измеряется в миллисекундах?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
5
0
2 324
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

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

оба, system.threading.timer и system.timers.timer поддерживают это.

Я уже обдумывал этот вариант, но меня интересует надежность и тому подобное.

George Mauer 29.09.2008 17:23

Создайте новый BackgroundWorker, спите, закройте.

var worker = new BackgroundWorker();
worker.DoWork += delegate {
  Thread.Sleep(30000); 
  DoStuff();
} 
worker.RunWorkerAsync();

Это займет процессор на 30000 мс, не так ли?

Nenad Dobrilovic 29.09.2008 17:22

@Nency - нет, я так не думаю, фоновый поток должен находиться в спящем режиме и поэтому не использовать процессорное время.

RickL 29.09.2008 17:28

Точно - Async будет означать, что он будет спать в новом потоке, поэтому потребление ЦП не больше, чем таймер в своем собственном потоке.

Unsliced 29.09.2008 17:55

просто установите галочку через X секунд, а в коде отметки выполните:

timer.enabled = false;

работал у меня.

Ответ принят как подходящий

Этот конструктор для System.Threading.Timer позволяет вам указать период. Если вы установите для этого параметра значение -1, он отключит периодическую сигнализацию и будет выполняться только один раз.

public Timer(
    TimerCallback callback,
    Object state,
    TimeSpan dueTime,
    TimeSpan period
)

!!! Святое дерьмо, Бен, никогда этого не знал, ты все запомнил MSDN или что-то в этом роде

George Mauer 29.09.2008 17:32

Не знал и этого. Мне всегда казалось, что QTimer :: singleshot Qt проще, но приятно знать, что таймер BCL может это сделать :)

OregonGhost 29.09.2008 17:35

В качестве вопроса: простой вызов Timer (callback, state, dueTime, period) .Start () может привести к тому, что таймер будет GC'd, поэтому мне все равно нужно сохранить объект Timer?

OregonGhost 29.09.2008 17:36

@OregonGhost, по-видимому, вы имеете в виду "(новый таймер (...)). Start ()". Вы не должны этого делать; Таймер IDisposable.

dan-gph 11.01.2010 08:21

Если вам нужен точный показатель времени, вам следует подумать об удвоении частоты таймера и использовании DateTime.Now для сравнения со временем начала. Таймеры и Thread.Sleep не обязательно являются точными в своих измерениях времени.

Вы можете использовать System.Timers.Timer с AutoReset = true или System.Threading.Timer с бесконечным периодом (System.Threading.Timeout.Infinite = -1) для однократного выполнения таймера.

В любом случае вы должны удалить свой таймер, когда закончите с ним (в обработчике событий для Timers.Timer или обратного вызова для Threading.Timer), если у вас нет повторяющегося интервала.

Другие вопросы по теме