2016-06-06 2 views
2

Вот сценарий:Как запустить таймер в определенное время в течение определенного времени?

Существует Textbox, в котором пользователь вводит время, при котором DispatcherTimer должен начать. Таймер установлен для работы в течение 4 часов, а событие Timer.Tick воспроизводит звук. Скажем, таймер начинается в 04:00:00 (HH: mm: ss), он должен работать до 8:00:00, а затем останавливаться. Затем, когда пользователь меняет время, скажем, до 09:00:00. Таймер должен работать до 13:00:00 и т. Д.

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

Вся помощь приветствуется. Заранее спасибо.

+2

Я бы не сказал, что 1 минута таймера является проблемой производительности для любого современного компьютера, но я бы использовал задачи Windows для такого рода сценариев. – Alex

+0

System.Threading.Timer дает вам возможность отсрочить запуск таймера, juste установите третий аргумент ctor в TimeSpan.FromHours (4). В работе таймера сделайте то, что вы хотите сделать (звук) – nkoniishvt

+0

Эта ссылка должна предоставить некоторую помощь: http://stackoverflow.com/questions/4529019/how-to-use-the-net-timer-class-to-trigger -an-event-at-specific-time –

ответ

2

Приведенный ниже метод запускает начальный таймер с интервалом на основе предоставленного времени (т. Е. Времени, введенного в ваше текстовое поле). Когда время достигнуто, он запускает дополнительный таймер, который будет срабатывать каждые четыре часа с этой точки.

Я использовал System.Timers таймер, а не Sytem.Threading Timer (потому что иронически таймер System.Threading не поточно!)

public void StartTimer(DateTime time) 
    { 
     const int fourHoursInMilliseconds = 4 * 3600 * 1000; 

     var fourHourTimer = new Timer() {Interval = fourHoursInMilliseconds}; 
     fourHourTimer.Elapsed += (sender, e) => 
     { 
      //code to handle the elapsed event here 
     }; 

     var span = time - DateTime.Now; 
     var timer = new Timer {Interval = span.TotalMilliseconds, AutoReset = false}; 
     timer.Elapsed += (sender, e) => { fourHourTimer.Start();}; 
     timer.Start(); 
    } 

Надежда это то, что вам нужно.

+0

Это было именно то, что мне нужно. Он короткий и точный. Спасибо. – thecodrr

1

У вас есть 2 проблемы.

  1. Как запустить таймер на заданное время (это называется диспетчеризации), смотри, например, this.
  2. Как с пересмотреть целевое время возможно работающего таймера.

Планирование (при условии, что ваше программное обеспечение будет запущено) в основном создает таймер, когда пользователь заканчивает свой ввод. Если пользователь меняет время, вы должны остановить этот таймер и снова запустить его с помощью нового времени.

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

Итак, в основном это будет 2 таймера, где один используется для запуска другого.

псевдокод:

DispatcherTimer _scheduler; 
DispatcherTimer _timer; 
DateTime _start; 
TimeSpan _duration; 

// call this when specified time is changed 
void Schedule(DateTime time) 
{ 
    _start = time; 
    // prevent any logic to run if timer is counting duration 
    if(_timer != null) 
     return; 
    // stop scheduler 
    if(_scheduler != null) 
     _scheduler.Stop(); 
    // create new scheduler 
    _scheduler = new DispatcherTimer { Interval = _start - DateTime.Now }; 
    _scheduler.Tick = (s, e) => 
    { 
     Start(_duration); // here scheduler will start timer 
     _scheduler.Stop(); // after that you don't need scheduler anymore 
     _scheduler = null; 
    } 
    _scheduler.Start(); 
} 

// call this when duration is changed 
void Start(TimeSpan duration) 
{ 
    _duration = duration; 
    // prevent from running before starting time 
    if(DateTime.Now < _start) 
     return; 
    // stop running timer 
    if(_timer != null) 
     _timer.Stop(); 
    // create timer to count duration including already expired time 
    _timer = new DispatcherTimer { Interval = _duration - (DateTime.Now - _start) }; 
    _timer.Tick = (s, e) => 
    { 
     ... // whatever 
     _timer.Stop(); // clean up 
     _timer = null; 
    } 
    _timer.Start(); 
} 

Я использую DispatcherTimer избежать Invoke при запуске другого DispatcherTimer. Оба Schedule() и Start() должны вызываться из потока пользовательского интерфейса (например, TextChanged).