Какой самый простой способ запланировать запуск функции в определенное время с помощью C # - PullRequest
5 голосов
/ 18 ноября 2011

Если в базе данных было много сообщений, которые я хотел отправить, и в каждой строке указывались дата и время отправки сообщения, а также флаг, если оно было отправлено.

Эти выигрышине всегда с фиксированными интервалами, и более 1 сообщения могут захотеть быть отправлены одновременно.

В этом случае он просто поставит их в очередь и отправит в порядке, когда они были созданы.

Легче всего сделать, просто чтобы функция запускалась снова и снова, после завершения она просто запускалась снова

Так что это будет:

  • Start Runи проверьте текущую дату / время
  • Проверьте наличие неотправленных сообщений
  • Отправьте все сообщения, которые должны быть отправлены до и до времени, когда он начал работать
  • Начать все сначаласнова и возьмите текущую дату / время

Моя проблема с этим заключается в том, будет ли ужасно неэффективно постоянно запускать метод, возможно, в течение нескольких часов или дней без фактической отправки сообщения.

TheОсновное напряжение в этом случае, я думаю, будет помещено в базу данных, оно будет постоянно получать запрос.

Есть ли лучший способ запланировать что-то подобное, чтобы это произошло.

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

Предлагает ли Workflow 4 что-нибудь подходящее для планирования?

Ответы [ 13 ]

2 голосов
/ 18 ноября 2011

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

Не уверен, что это так сложно, как вы хотите

1 голос
/ 18 ноября 2011

В нескольких ответах предлагалось отправить несколько сообщений, затем вызывать sleep до тех пор, пока не должно быть отправлено следующее сообщение.

Важно, как вы спите в этом случае.

Теоретически вы можете указать потоку спать несколько часов, однако, если в течение этого времени приложение (или служба) будет закрыто, у вас возникнут проблемы.Процесс будет прерван, очистка не будет выполнена.Это не идеально.

Не путайте между концепцией опроса для работы и спящего между опросами.

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

Что бы я сделал.,.

Написать службу windows.У службы есть один активный поток, который опрашивает базу данных, проверяет, есть ли какие-либо сообщения из-за отправки и отправляет их.Затем он будет опрашивать с настраиваемой задержкой (1 минута, 5 минут, 1 час, что бы ни устраивало).
Однако он никогда не будет спать дольше секунды, пока он ожидает опроса базы данных.

Если вы можете быть уверены, что сообщения могут быть добавлены только для отправки после последнего сообщения в БД?Если это так, вы можете проверить время следующего сообщения и не опрашивать до этого времени.

Однако, если я обнаружу, что следующее сообщение не нужно отправлять в течение 5 часов, возможно, что в то время как яжду, что было добавлено сообщение, которое должно быть отправлено через 30 минут?
Если это так, то вы никогда не сможете доверять «Время следующего сообщения» и не опрашивать до этого момента, вам придется постоянно опрашивать ваш фиксированный интервал NB стоит еще раз сказать, ваш интервал опроса и ваш интервал сна не одно и то же.

1 голос
/ 18 ноября 2011

Вы можете использовать службу Windows для этого. Или, если вы используете MSSQL, вы можете даже использовать задание агента SQL Server.

1 голос
/ 18 ноября 2011

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

0 голосов
/ 18 ноября 2011

Многие базы данных позволяют запускать события триггерами, например. «после вставки». Триггер запускается процессом / потоком базы данных, и действия, которые он может выполнять, зависят от базы данных. Например, он может вызвать процедуру C или java, которая сигнализирует именованный семафор, которого ожидает ваш e-mail или exec. приложение электронной почты напрямую. Посмотрите на «триггер» или «создать триггер» для вашей базы данных.

0 голосов
/ 18 ноября 2011

Мы делаем это в финансовом учреждении, чтобы рассылать внутренние электронные письма из наших приложений в интрасети. Каждые 15 минут программа планирования (корпоративный планировщик, а не запланированная задача Windows) запускает задание. У нас есть представление с именем PendingEmail поверх таблицы с именем EmailQueue, в котором перечисляется только то, что должно быть отправлено при этом (таблица EmailQueue имеет PopDate, которая является датой вступления в силу, когда электронная почта должна быть отправлена). Приложение запускает электронную почту для всего, что было найдено в представлении PendingEmails.

Задание отправляет максимальный размер пакета электронных писем каждые 15 минут, помечая каждую запись тем, была ли она успешно отправлена ​​или была ли ошибка (неверный адрес электронной почты и т. Д.) И что было Exception, и был ли Мы хотели бы попробовать отправить его в следующий раз. Он обновляет эту таблицу EmailQueue сразу, а не каждую запись в отдельности. Размер партии был установлен таким образом, чтобы работа не занимала более 15 минут и не давила на себя.

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

См. Этот пост на Thread.Sleep() против Timer класса:

0 голосов
/ 18 ноября 2011

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

0 голосов
/ 18 ноября 2011

Вы можете использовать этот .NET Scheduled Timer для проверки временных интервалов и запуска функции (отправки сообщений) через определенные промежутки времени ....

0 голосов
/ 18 ноября 2011

Недавно я реализовал службу Windows, которая использовала класс IntervalHeap в библиотеке классов коллекции C5 .Затем я добавил слой постоянства, который отслеживает элементы и их интервалы в случае остановки / сбоя службы.

Работал в течение нескольких месяцев и работал очень хорошо.

0 голосов
/ 18 ноября 2011

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

В качестве альтернативы можно использовать БД с «поддержкой уведомлений», что делает весь процесс управляемым событиями, т. Е. БД отправляет вам событие всякий раз, когда требуется сообщение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...