2013-09-13 6 views
2

Я хотел бы создать таймер, который вызывает метод каждые 24 часа в определенное время. Я не хочу делать это через Планировщик Windows, но вместо этого должен быть выполнен в коде. Вот код, я использую в настоящее время с помощью:Таймер каждые 24 часа в определенное время

DateTime now = DateTime.Now; 
DateTime today = now.Date.AddHours(16); 
DateTime next = now <= today ? today : today.addDays(1); 

Systems.Threading.TimerCallback callback = new TimerCallback(DisplayMessage); 
Systems.Threading.Timer timer = new System.Threading.Timer(callback, null, next - now, TimeSpan.FromHours(24)); 

Моя проблема заключается в том, что если next заканчивается время всего в нескольких минутах ходьбы от текущего времени, то код работает и отображает сообщение через DisplayMessage(). Если разница во времени превышает несколько минут, код не работает, никаких исключений, сбоев или чего-либо еще. Я попытался разместить записи журнала, окна сообщений и точки останова внутри DisplayMessage(), чтобы убедиться, что я правильно вижу, когда вызывается DisplayMessage(), но не повезло.

+2

Вы посмотрели Quartz.net. – phuzi

+9

Очевидный первый вопрос: вы держите ссылку на 'timer' до обратного вызова? Это необходимо для того, чтобы это не было GC'd. – McGarnagle

+0

@McGarnagle, это, наверное, то, что есть, я попробую его и отчитаюсь завтра. Это объясняет, почему он работает в более короткие сроки. – Joshua

ответ

-2

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

+0

Запуск его каждые 24 часа - это одно из обычных применений таймера – reggaeguitar

0

Вот пример работы.

public class Scheduler { 
    private readonly List<Task> _Tasks; 
    private Timer _Timer; 

    public Scheduler() { 
     _Tasks = new List<Task>(); 
    } 

    public void ScheduleTask(Task task) { 
     _Tasks.Add(task); 
    } 

    public void CancelTask(Task task) { 
     _Tasks.Remove(task); 
    } 

    //Start the timer. 
    public void Start() { 
     //Set the interval based on what amount of accurcy you need. 
     _Timer = new Timer { 
      Interval = 1000 
     }; 

     _Timer.Elapsed += (sender, args) => UpdateTasks(); 
     _Timer.Enabled = true; 
    } 

    //Check to see if any task need to be executed. 
    private void UpdateTasks() { 
     for (int i = 0; i < _Tasks.Count; i++) { 
      Task task = _Tasks[i]; 

      if (task.ExecuteTime >= DateTime.Now) { 
       task.Callback(); 
       _Tasks.Remove(task); 
      } 

      _Tasks.Remove(task); 
     } 
    } 

    //Stop the timer when you are done. 
    public void Stop() { 
     _Timer.Dispose(); 
    } 
} 

//Use this to schedule a task. 
public class Task { 
    public DateTime ExecuteTime { get; set; } 
    public Action Callback { get; set; } 

    public Task(DateTime executeTime, Action callback) { 
     ExecuteTime = executeTime; 
     Callback = callback; 
    } 
} 
Смежные вопросы