У меня есть служба, написанная на C # (.NET 1.1), и я хочу, чтобы она выполняла некоторые действия по очистке в полночь каждую ночь. Я должен сохранить весь код, содержащийся в службе, так как же проще всего этого добиться? Использование Thread.Sleep()
и проверка продления времени?
c#
windows-services
scheduling
scheduled-tasks
ctrlalt3nd
источник
источник
Ответы:
Я бы не стал использовать Thread.Sleep (). Либо используйте запланированную задачу (как упоминали другие), либо настройте таймер внутри своей службы, который периодически срабатывает (например, каждые 10 минут), и проверьте, изменилась ли дата с момента последнего запуска:
private Timer _timer; private DateTime _lastRun = DateTime.Now.AddDays(-1); protected override void OnStart(string[] args) { _timer = new Timer(10 * 60 * 1000); // every 10 minutes _timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed); _timer.Start(); //... } private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { // ignore the time, just compare the date if (_lastRun.Date < DateTime.Now.Date) { // stop the timer while we are running the cleanup task _timer.Stop(); // // do cleanup stuff // _lastRun = DateTime.Now; _timer.Start(); } }
источник
Проверьте Quartz.NET . Вы можете использовать его в службе Windows. Он позволяет запускать задание на основе настроенного расписания и даже поддерживает простой синтаксис «cron job». Я добился большого успеха с этим.
Вот краткий пример его использования:
// Instantiate the Quartz.NET scheduler var schedulerFactory = new StdSchedulerFactory(); var scheduler = schedulerFactory.GetScheduler(); // Instantiate the JobDetail object passing in the type of your // custom job class. Your class merely needs to implement a simple // interface with a single method called "Execute". var job = new JobDetail("job1", "group1", typeof(MyJobClass)); // Instantiate a trigger using the basic cron syntax. // This tells it to run at 1AM every Monday - Friday. var trigger = new CronTrigger( "trigger1", "group1", "job1", "group1", "0 0 1 ? * MON-FRI"); // Add the job to the scheduler scheduler.AddJob(job, true); scheduler.ScheduleJob(trigger);
источник
Ежедневная задача? Похоже, это должно быть просто запланированное задание (панель управления) - здесь нет необходимости в обслуживании.
источник
Это должна быть настоящая услуга? Можете ли вы просто использовать встроенные запланированные задачи в панели управления Windows.
источник
Я делаю это с помощью таймера.
Запустите серверный таймер, пусть он проверяет часы / минуты каждые 60 секунд.
Если это правильный час / минута, запустите процесс.
На самом деле у меня это абстрагировано в базовый класс, который я называю OnceADayRunner.
Позвольте мне немного поправить код, и я выложу его здесь.
private void OnceADayRunnerTimer_Elapsed(object sender, ElapsedEventArgs e) { using (NDC.Push(GetType().Name)) { try { log.DebugFormat("Checking if it's time to process at: {0}", e.SignalTime); log.DebugFormat("IsTestMode: {0}", IsTestMode); if ((e.SignalTime.Minute == MinuteToCheck && e.SignalTime.Hour == HourToCheck) || IsTestMode) { log.InfoFormat("Processing at: Hour = {0} - Minute = {1}", e.SignalTime.Hour, e.SignalTime.Minute); OnceADayTimer.Enabled = false; OnceADayMethod(); OnceADayTimer.Enabled = true; IsTestMode = false; } else { log.DebugFormat("Not correct time at: Hour = {0} - Minute = {1}", e.SignalTime.Hour, e.SignalTime.Minute); } } catch (Exception ex) { OnceADayTimer.Enabled = true; log.Error(ex.ToString()); } OnceADayTimer.Start(); } }
Суть метода заключается в проверке e.SignalTime.Minute / Hour.
Там есть крючки для тестирования и т. Д., Но так может выглядеть ваш истекший таймер, чтобы все это работало.
источник
Как уже писали другие, таймер - лучший вариант в описанном вами сценарии.
В зависимости от ваших конкретных требований ежеминутная проверка текущего времени может не потребоваться. Если вам не нужно выполнять действие точно в полночь, а только в течение одного часа после полуночи, вы можете воспользоваться подходом Мартина, проверяя только, изменилась ли дата.
Если причина, по которой вы хотите выполнить действие в полночь, заключается в том, что вы ожидаете низкой нагрузки на свой компьютер, лучше позаботьтесь: такое же предположение часто делают другие, и внезапно у вас есть 100 действий по очистке, начинающихся между 0:00 и 0 : 01 утра
В этом случае вам следует подумать о том, чтобы начать очистку в другое время. Я обычно делаю это не в час, а в полчаса (я предпочитаю 1.30).
источник
Я бы посоветовал вам использовать таймер, но установить его так, чтобы он проверял каждые 45 секунд, а не минуту. В противном случае вы можете столкнуться с ситуациями, когда при большой нагрузке проверка на определенную минуту пропускается, потому что между временем срабатывания таймера и временем, когда ваш код запускается и проверяет текущее время, вы могли пропустить целевую минуту.
источник
Вы также можете попробовать TaskSchedulerLibrary здесь http://visualstudiogallery.msdn.microsoft.com/a4a4f042-ffd3-42f2-a689-290ec13011f8
Реализуйте абстрактный класс
AbstractScheduledTask
и вызовитеScheduleUtilityFactory.AddScheduleTaskToBatch
статический методисточник
Для тех, кто обнаружил, что вышеуказанные решения не работают, это связано с тем, что у вас может быть
this
внутри вашего класса, что подразумевает метод расширения, который, как говорится в сообщении об ошибке, имеет смысл только для неуниверсального статического класса. Ваш класс не статичен. Это не похоже на то, что имеет смысл в качестве метода расширения, поскольку он действует на рассматриваемый экземпляр, поэтому удалитеthis
.источник
Попробуй это:
public partial class Service : ServiceBase { private Timer timer; public Service() { InitializeComponent(); } protected override void OnStart(string[] args) { SetTimer(); } private void SetTimer() { if (timer == null) { timer = new Timer(); timer.AutoReset = true; timer.Interval = 60000 * Convert.ToDouble(ConfigurationManager.AppSettings["IntervalMinutes"]); timer.Elapsed += new ElapsedEventHandler(timer_Elapsed); timer.Start(); } } private void timer_Elapsed(object source, System.Timers.ElapsedEventArgs e) { //Do some thing logic here } protected override void OnStop() { // disposed all service objects } }
источник