Лучший способ запуска запланированных задач

219

Сегодня мы создали консольное приложение для запуска запланированных задач для нашего веб-сайта ASP.NET. Но я думаю, что этот подход немного склонен к ошибкам и его трудно поддерживать. Как выполнить запланированную задачу (в среде Windows/IIS/ASP.NET)

Обновление:

Примеры задач:

  • Отправка электронной почты из очереди электронной почты в базе данных
  • Удаление устаревших объектов из базы данных
  • Получение статистики из Google AdWords и заполнение таблицы в базе данных.
  • 0
    Каков пример задач, которые вы выполняете?
  • 3
    Вам нужно проверить atrigger.com
Показать ещё 1 комментарий
Теги:
iis
scheduled-tasks

16 ответов

72
Лучший ответ

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

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

  • 3
    Это решение, которое я закончил. Вместо пользовательского веб-сервиса я использую планировщик windows + curl. В чем выгода от использования службы Windows.
  • 2
    Никакой пользы, все в том, как ты это собрал. Твое отличное решение.
Показать ещё 12 комментариев
118

Этот метод Джеффа Этвуда для Stackoverflow является самым простым методом, с которым я столкнулся. Он полагается на механизм "обратного вызова", удаленный из кэша, в систему кеша ASP.NET.

Обновление: Stackoverflow перерос этот метод. Он работает только во время работы веб-сайта, но это очень простой метод, который полезен для многих людей.

Также проверьте Quartz.NET

  • 12
    Так что же произойдет, если приложение не запущено, но запланированное задание должно произойти?
  • 2
    Это также может замедлить работу пользователя, если на этот раз задача займет некоторое время. Я предпочитаю, чтобы пользователь не порождал для меня свое обслуживание / задачи.
Показать ещё 10 комментариев
30

Создайте пользовательскую службу Windows.

У меня были некоторые критически важные задачи, настроенные как запланированные консольные приложения, и их было сложно поддерживать. Я создал службу Windows с "heartbeat", которая проверяет расписание в моей БД каждые пару минут. Это получилось очень хорошо.

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

  • 7
    К вашему сведению, ссылка сейчас мертва.
  • 1
    @CharlesBurns, вы всегда можете просмотреть неработающие ссылки с archive.org: web.archive.org/web/20090919131944/http://www.dotheweb.net/…
17

Я нашел, что это будет легко для всех участников:

  • Создайте метод webservice, например DoSuchAndSuchProcess
  • Создайте консольное приложение, которое вызывает этот веб-метод.
  • Запланировать консольное приложение в планировщике задач.

Используя эту методологию, вся бизнес-логика содержится в вашем веб-приложении, но у вас есть надежность диспетчера задач Windows или любого другого менеджера коммерческих задач, чтобы отбросить его и записать любую возвращаемую информацию, такую ​​как отчет о выполнении. Использование веб-службы вместо публикации на странице имеет немного преимуществ, потому что проще получить возвращаемые данные из веб-службы.

9

Зачем изобретать колесо, используйте класс Threading и Timer.

    protected void Application_Start()
    {
        Thread thread = new Thread(new ThreadStart(ThreadFunc));
        thread.IsBackground = true;
        thread.Name = "ThreadFunc";
        thread.Start();
    }

    protected void ThreadFunc()
    {
        System.Timers.Timer t = new System.Timers.Timer();
        t.Elapsed += new System.Timers.ElapsedEventHandler(TimerWorker);
        t.Interval = 10000;
        t.Enabled = true;
        t.AutoReset = true;
        t.Start();
    }

    protected void TimerWorker(object sender, System.Timers.ElapsedEventArgs e)
    {
        //work args
    }
  • 7
    Вам не нужно создавать поток, чтобы запустить таймер ...
  • 4
    Я тоже не думаю, что это идеальное решение.
Показать ещё 3 комментария
8

Используйте Планировщик Windows для запуска веб-страницы.

Чтобы предотвратить запуск злоумышленников или поисковых роботов, при настройке запланированной задачи просто вызовите веб-страницу с помощью запроса, то есть: mypage.aspx? from = scheduletask

Затем в загрузке страницы просто используйте условие:   if (Request.Querystring [ "from" ] == "scheduletask" )   {   //executetask   }

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

  • 5
    А еще лучше - использовать соленый алгоритм хеширования, который фактически проверяет строку запроса с немного большей безопасностью, чем волшебная фраза. Требование будет примерно таким: mypage.aspx? Salt = foo & hash = 1223523jbhdgu13t1. Вам просто нужно иметь одинаковый алгоритм хеширования как на сервере, так и на клиенте. Также добавьте жесткий лимит на сервере; сохранить, когда это было выполнено и предотвратить выполнение слишком быстро. Я могу быть параноиком, хотя.
  • 13
    Еще более безопасно использовать планировщик Windows для запуска веб-страницы, которая проверяет, поступает ли запрос с самого сервера: Request.IsLocal >> только сам сервер может выполнять запланированные задачи, никто другой.
4

Эта библиотека работает как шарм http://www.codeproject.com/KB/cs/tsnewlib.aspx

Он позволяет вам управлять запланированными задачами Windows непосредственно через ваш код .NET.

3

Кроме того, если ваше приложение использует SQL SERVER, вы можете использовать SQL Agent для планирования ваших задач. Это то место, где мы обычно ставим повторяющийся код, который управляется данными (напоминания по электронной почте, плановое обслуживание, чистки и т.д.). Отличная функция, встроенная с агентом SQL, - это параметры уведомления об отказах, которые могут предупредить вас о сбое критической задачи.

2

Если у вас есть сервер, вы должны использовать планировщик задач Windows. Использовать AT/? из командной строки, чтобы просмотреть параметры.

В противном случае из веб-среды вам может понадобиться сделать что-то неприятное, например, настроить другую машину, чтобы делать запросы на определенную страницу с временным интервалом.

2

Я использовал Abidar успешно в проекте ASP.NET(здесь некоторые справочная информация).

Единственная проблема с этим методом заключается в том, что задачи не будут выполняться, если веб-приложение ASP.NET выгружается из памяти (т.е. из-за низкого использования). Одна вещь, которую я пробовал, - это создать задачу, которая попадает в веб-приложение каждые 5 минут, сохраняя ее, но это, похоже, не работает надежно, поэтому теперь я использую планировщик Windows и базовое консольное приложение для этого.

Идеальное решение - это создание службы Windows, хотя это может быть невозможно (например, если вы используете общедоступную среду хостинга). Это также делает вещи немного проще с точки зрения обслуживания, чтобы держать вещи в веб-приложении.

2

Я не уверен, какие запланированные задачи вы имеете в виду. Если вы имеете в виду такие вещи, как "каждый час, обновить foo.xml", используйте систему Windows Scheduled Tasks. (Команда "at" или через контроллер.) Попросите либо запустить консольное приложение, либо запросить специальную страницу, которая запускает процесс.

Изменить: я должен добавить, это способ OK, чтобы ваше приложение IIS работало и в запланированных точках. Поэтому предположим, что вы хотите проверять свою БД каждые 30 минут и отправлять напоминания пользователям о некоторых данных, вы можете использовать запланированные задачи для запроса этой страницы и, следовательно, получать обработку IIS.

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

1

Вы можете легко создать службу Windows, которая запускает код с интервалом, используя метод ThreadPool.RegisterWaitForSingleObject. Это действительно гладкий и довольно простой в настройке. Этот метод является более оптимизированным подходом для использования любого из таймеров в Framework.

Посмотрите на приведенную ниже ссылку для получения дополнительной информации:

Выполнение периодического процесса в .NET с помощью службы Windows:
http://allen-conway-dotnet.blogspot.com/2009/12/running-periodic-process-in-net-using.html

1

Здесь другой способ:

1) Создайте веб-сайт "heartbeat" script, который отвечает за запуск задач, если они являются DUE или просрочены для запуска.

2) Создайте запланированный процесс где-нибудь (желательно на том же веб-сервере), который попадает на веб-страницу и заставляет его запускаться с регулярным интервалом. (например, задача планирования окон, которая тихо запускает тепловой поток script с помощью IE или whathaveyou)

Тот факт, что код задачи содержится в веб-интерфейсе script, предназначен исключительно для сохранения кода внутри кодовой базы веб-приложения (предполагается, что оба они зависят от каждого другой), что будет проще для веб-разработчиков.

Альтернативный подход заключается в создании исполняемого сервера script/program, который выполняет всю работу расписания и запускает сам исполняемый файл в качестве запланированной задачи. Это может обеспечить фундаментальную развязку между веб-приложением и запланированной задачей. Следовательно, если вам нужно, чтобы ваши запланированные задачи выполнялись даже в том случае, если веб-приложение/база данных может быть недоступна или недоступна, вы должны пойти с этим подходом.

  • 1
    @Matias, а почему бы просто запланированному процессу не выполнять настоящую работу?
0

Мы также используем консольные приложения. Если вы используете инструменты ведения журнала, такие как Log4net, вы можете правильно контролировать их выполнение. Кроме того, я не уверен, как их сложнее поддерживать, чем веб-страницу, так как вы можете делиться одними и теми же библиотеками кода между ними, если они правильно разработаны.

Если вы против того, чтобы эти задачи выполнялись по расписанию, у вас может быть веб-страница в вашем административном разделе вашего веб-сайта, которая действует как очередь. Пользователь ставит запрос на выполнение задачи, он в свою очередь вставляет в таблицу MyProcessQueue пустую запись данных, а ваша запланированная задача проверяет каждые X минут для новой записи в MyProcessQueue. Таким образом, он запускается только тогда, когда клиент хочет его запустить.

Надеюсь, что эти рекомендации помогут.

0

Один из вариантов - настроить службу Windows и получить ее для выполнения запланированной задачи.

В winforms я использовал Timers put, не думаю, что это будет хорошо работать в ASP.NET

-1

Новая библиотека классов планировщика заданий для .NET.

Примечание. Поскольку эта библиотека была создана, Microsoft представила новый планировщик задач (Task Scheduler 2.0) для Windows Vista. Эта библиотека является оболочкой для интерфейса Task Scheduler 1.0, которая по-прежнему доступна в Vista и совместима с Windows XP, Windows Server 2003 и Windows 2000.

http://www.codeproject.com/KB/cs/tsnewlib.aspx

  • 0
    Пожалуйста, удалите. Ответ дан ниже. дублировать

Ещё вопросы

Сообщество Overcoder
Наверх
Меню