Как реализовать задание, которое выполняется каждый час, но также может запускаться со страниц .aspx? - PullRequest
2 голосов
/ 20 марта 2009

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

Например, могу ли я ...

Создайте одноэлементный класс, который запускает метод по таймеру, и создайте его экземпляр в файле global.asax. Затем, поскольку это одноэлементный файл, я могу вызывать его со своих обычных страниц ASPX и вызывать метод всякий раз, когда захочу. Возможно, мне понадобится использовать эту функцию блокировки в C #, чтобы проверить, запущен ли метод.

В последнее время я слышал некоторые разговоры о том, что синглтоны - это "зло", но это, кажется, идеально подходит для этого. Как вы думаете? Заранее спасибо.

Ответы [ 7 ]

8 голосов
/ 20 марта 2009

Таймеры и блокировки (которые предназначены для синхронизации доступа к базе данных) - плохая идея в Интернете; у вас может быть ноль, один или несколько пулов приложений на разных серверах. Они могут перерабатывать в любое время и не будут раскручиваться до тех пор, пока не понадобятся. По сути, это не помешает вам забить БД из нескольких источников.

Лично я бы хотел написать сервис для выполнения этой работы (либо db-опрос, либо через WCF и т. Д.), Либо использовать db (SP или аналогичный) - установить флаг в строке таблицы. сказать «в процессе», выполнить работу в БД и снять флажок (повторяющиеся попытки завершаются немедленно во время выполнения).

1 голос
/ 20 марта 2009

Еще один вариант, который Джоэл Спольски упомянул в одном из SO Podcasts, я думаю, это было что-то №20. Необходимо установить пустой объект Cache при запуске приложения с определенной датой истечения срока действия, а в CacheItemRemovedCallback сделать вызов страницы или выполнить некоторую работу, а затем сбросить пустой объект кэша.

Я, вероятно, ужасно неправильно цитирую его, поэтому я рекомендую вам прослушать или самостоятельно просмотреть стенограммы.

1 голос
/ 20 марта 2009

Я бы сделал это так

  1. Создание нормальной страницы ASP.NET, которая выполняет обработку
  2. Украсть Заимствовать LFSR Consultings идея флага в БД, который выполняет работу по проверке, запущен ли в данный момент процесс
  3. Используйте обычный планировщик задач cronjob или windows для регулярного вызова веб-страницы.

И Одиночки не являются злом они просто легко подвергаются насилию.

0 голосов
/ 20 марта 2009

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

0 голосов
/ 20 марта 2009

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

Edit: После того, как я увидел вашу ревизию о том, что вы не хотите, чтобы они запускались одновременно, мы обычно просто контролируем это с помощью флага базы данных, как говорили некоторые другие, ничего особенного, но он выполняет свою работу

0 голосов
/ 20 марта 2009

Канонический способ написания синглтона оказывается не поточно-ориентированным. Особенно в веб-среде, где потоки даже не должны быть на одной машине!

Если вы действительно хотите сделать «синглтон», думайте о нем как об услуге, которую вы когда-либо развертываете только на одной машине. Затем используйте транзакционную семантику вашей базы данных, как предлагает Марк Гравелл, для синхронизации блокировок.

0 голосов
/ 20 марта 2009

Как насчет того, чтобы просто установить флаг в базе данных и проверить его, чтобы определить, выполняется задание или нет? Кажется проще ИМО.

...