Страницы

Поиск по вопросам

Показаны сообщения с ярлыком планировщик-задач. Показать все сообщения
Показаны сообщения с ярлыком планировщик-задач. Показать все сообщения

среда, 25 декабря 2019 г.

Как использовать нерекомендуемые компоненты в планировщике заданий?

#windows #администрирование #планировщик_задач


В планировщике заданий во время добавления нового задания, помимо открытия приложения,
имеются функции вывода сообщений и отправки e-mail'а.

При выборе одной из них выскакивает уведомление, мол, ошибка : выбран нерекомендуемый
компонент.

Затем встаёт вполне логичный вопрос: зачем они там нужны, и можно ли обойти это назойливое
уведомление, всё-таки использовав, допустим, вывод сообщения?
    


Ответы

Ответ 1



Они не рекомендованы потому, как устарели. ЕМНИП, на нашем англо-французском ноутбуке этот термин звучит как 'obsolète' - устаревший. Это не значит, что ими нельзя пользоваться, но стоит от этого отказаться, так как компонент может исчезнуть даже в следующем обновлении, либо испытывает определенные проблемы с окружением, либо потенциально небезопасен. К тому же, если не ошибаюсь, использование таких компонентов приводит к лишним строкам в журналах Windows, а их и так разбирать - не сахар :) Поэтому стоит переключиться на более современные программы и скрипты. Отправить почту можно с помощью Powershell: Send-MailMessage -From 'Vasja ' -To 'Petja ' -Subject 'Всё пропало, шеф! :)' Вывести сообщение с помощью msg: msg Petja Всё пропало, шеф!

четверг, 28 ноября 2019 г.

Выполнение операций по расписанию

#c_sharp #.net #планировщик_задач


Необходимо проводить определенные действия по расписанию, абстрактный пример:


в понедельник в 12:00 взять файлы из папки
во вторник в 13:39 создать папку с файлами
в третью пятницу в 7:03 посчитать количество файлов


Целесообразно ли будет для этого использовать timer с Interval в минуту и в его Tick
проверять время и день недели?

private void timer1_Tick(object sender, EventArgs e)
{
   var currentTime = DateTime.Now.TimeOfDay;
   var currentDow = DateTime.Now.DayOfWeek;
   var oneMinute = new TimeSpan(0, 1, 0);
   if ((currentDow  == DayOfWeek.Monday)&&(currentTime-timeMonday


Ответы

Ответ 1



Нет, этого совершенно недостаточно. Windows не дает никаких гарантий, что ваш таймер и правда будет вызываться каждую минуту. С такими сравнениями вы запросто пропустите нужное время или отработаете два раза. Более правильно будет хранить для каждой задачи следующее время запуска и запускать задачу когда текущее время больше запланированного (но не вышло за пределы некоторого разумного интервала). Про строгие сравнения времени забудьте в принципе! PS для справки - мой старый ответ на смежную тематику: https://ru.stackoverflow.com/a/593736/178779

Ответ 2



Лучше используйте библиотеку Quartz.net, она специально предназначена для таких целей и очень гибко настраивается. Также она есть в nuget: Install-Package Quartz Либо можно вообще воспользоваться средствами планировщика задач Windows.

Ответ 3



Hangfire — планировщик задач для .NET На мой взгляд это самый лучший многопоточный и масштабируемый планировщик задач. Легкая установка с помощью NuGet Install-Package Hangfire С коробки есть красивый дашборд со всей статистикой и всеми запланированными заданиями. Краткий обзор на habrahabr

Ответ 4



Я бы разделил программу на 3 модуля и использовал бы стандартный Windows Task Scheduler. Тестировать будет удобнее + всегда понятно, какой компонент работает неверно

Ответ 5



Можете посмотреть в сторону TopShelf + Quartz, очень удобно + есть всё что нужно (модули для DI, планирование как угодно). Для этого Вам нужно будет разделить работы (создать классы производные от IJob), потом описать механизм планирования например так: private static void ScheduleRepeatableJobIn**(ServiceConfigurator serviceConfigurator, int timeout) where T : IJob { serviceConfigurator.ScheduleQuartzJob(configurator => configurator.WithSimpleRepeatableSchedule(TimeSpan.From**(timeout), typeof(T).Name)); } И потом просто запустить сервис/консоль так: HostFactory.Run(x => { x.Service(s => { ScheduleRepeatableJobInMinutes(s, timeout); ScheduleRepeatableJobInMinutes(s, timeout); s.WhenStarted(tc => tc.Start()); s.WhenStopped(tc => tc.Stop()); }); }); P.S. Пример кода показательный, для решение Вашей проблемы Вам нужно будет написать свою логику планирования.

среда, 17 июля 2019 г.

Нужна информация по шедулерам для встроенных систем

Добрый день.
Когда-то давно я применял шедулер для микроконтроллера http://www.ucos-ii.com. Довольно приятная вещь, хотя и с ограниченной функциональностью. Но с тех пор эта контора заглохла. Подскажите информацию по подобным вещам. Может быть кто-нибудь знает форум, где обсуждаются похожие вещи.
Спасибо.
UPD1:
Оказалось, что контора не заглохла, просто переехала на другой хостинг: https://www.micrium.com/. И при этом контору купил Silicon Labs.


Ответ

Подобных ОСРВ для микроконтроллеров довольно много, перечень можно посмотреть здесь. Достаточно популярной является FreeRTOS (она бесплатна и по ней много материала в сети), embOS, MicroC/OS от Micrium

пятница, 12 июля 2019 г.

Ошибка при повторном создании папки в планировщике задач Delphi (CoTaskScheduler)

Необходимо создать папку в планировщике задач имея переменную ts типа TaskSchd.ITaskService.
ts := CoTaskScheduler.Create(); ts.Connect('', '', '', ''); tf := ts.GetFolder('\').CreateFolder('test_F', null);
Первый запуск программы создаёт папку без проблем. Но, при повторном запуске, система сообщает об ошибке "Данная папка уже существует". Пытался через try except решать проблему, но не получилось (Сначала появлялось окно с ошибкой, а потом запускался обработчик).
Как обработать это исключение, чтобы не появлялось уведомление системы об ошибке?
P.S. Другие методы работы с планировщиком не подходят, только через приведённые в коде объекты.


Ответ

Вам должна помочь установка режима отображения системных ошибок SetThreadErrorMode. Она запрещает системе отображать диалоговые окна с ошибками и система вместо этого отправляет ошибку вызывающему потоку.
Если в вашей версии Delphi эта функция не объявлена, объявить ее можно так:
function SetThreadErrorMode(uNewMode: DWORD; var uOldMode: DWORD): BOOL; stdcall; external kernel32 name 'SetThreadErrorMode';
В моем случае, это помогло избавиться от сообщения типа "Отсутствует носитель", когда я пытался получить объем логического диска, который находился на картридере, в момент отсутствия карты памяти.
uses Windows; var OldErrorMode: Cardinal; begin SetThreadErrorMode(SEM_FAILCRITICALERRORS, OldErrorMode); try // действия, которые могут привести к появлению нежелательного диалога finally SetThreadErrorMode(OldErrorMode, OldErrorMode); end; end;

понедельник, 1 октября 2018 г.

Выполнение операций по расписанию

Необходимо проводить определенные действия по расписанию, абстрактный пример:
в понедельник в 12:00 взять файлы из папки во вторник в 13:39 создать папку с файлами в третью пятницу в 7:03 посчитать количество файлов
Целесообразно ли будет для этого использовать timer с Interval в минуту и в его Tick проверять время и день недели?
private void timer1_Tick(object sender, EventArgs e) { var currentTime = DateTime.Now.TimeOfDay; var currentDow = DateTime.Now.DayOfWeek; var oneMinute = new TimeSpan(0, 1, 0); if ((currentDow == DayOfWeek.Monday)&&(currentTime-timeMonday if ((currentDow == DayOfWeek.Tuesday)&&(currentTime-timeTuesday if ((currentDow == DayOfWeek.Friday)&&(MyDoWInMonth(DateTime.Now).Equals(3))&(currentTime-timeFriday

Ответ

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

PS для справки - мой старый ответ на смежную тематику: https://ru.stackoverflow.com/a/593736/178779