Хотел бы выполнить запрос один раз в день в ASP.NET MVC - PullRequest
4 голосов
/ 09 июля 2011

Я бы хотел, чтобы мое приложение ASP.NET MVC выполняло запрос один раз в день.Каков рекомендуемый способ сделать это?

Моя первая мысль - установить таймер в Global.asax, который отключается каждые 24 часа, а затем вызвать мой запрос из обработчика Elapsed.Есть какие-нибудь подводные камни с этим?Есть ли лучший способ?

Редактировать

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

Изменить 2

Пару подробностей

  1. Запрос на самом деле является INSERT, а не SELECT.Цель состоит в том, чтобы добавить запись «продление» для любого участника, который должен продлить свое членство в конце месяца.
  2. Я использую SQL Server Compact (это очень маленькая база данных).

Ответы [ 4 ]

8 голосов
/ 09 июля 2011

Должен ли он возникать на веб-уровне?Кто будет там, чтобы потреблять HTML?Как правило, периодические запросы SQL планируются в базе данных.В случае MS SQL Server - через средство работы агента SQL.SQL Server может даже отправлять электронную почту.

RE: edit2: Должен был сказать об этом прямо сейчас.SQL Server Compact - это не то же самое, что SQL Server - например, он не имеет SQL Agent IIRC.Тем не менее, вызов веб-слоя является излишним.Я бы использовал файл Windows Scripting Host (.js) в сочетании с планировщиком задач Windows.Файлы WSH могут подключаться к базам данных через ADO и делать что угодно - вставлять, выбирать, что угодно.

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

Edit2: поэтому нет административного доступа.Вы должны действительно рассказать все эти детали в вопросе.В этом случае я бы прошел бы через веб-слой в конце концов, но планирование было бы на МОЕМ конце - где у меня есть контроль.Запустите планировщик задач и запустите на сервере HTTP-URL.Для вызова URL вы можете использовать что-то вроде бесплатной утилиты CURL .Недостатком запуска IE по расписанию является то, что окно остается открытым.

IIS не является механизмом планирования.

Edit3 re: comment: извините, я неправильно понял природу ваших настроек.Мой собственный опыт омрачил мое суждение :) Можете ли вы просто выполнить проверку во время каждой операции входа в систему, и, если с момента последней операции обслуживания прошло какое-то время, запустите ее прямо тогда и там?Сколько времени занимает обслуживание?Если это ~ 1мин +, имеет смысл запускать его в рабочем потоке, чтобы вошедший в систему пользователь не заставлял себя ждать.

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

1 голос
/ 09 июля 2011

Я делаю это, помещая некоторую фальшивую информацию в «Кэш» и помещая желаемый период времени, затем направляю событие «_onCacheRemove», делаю все, что я хочу, затем воссоздаю «CacheItem» снова:например,

Я помещаю свои задачи в Enum на время, когда я хочу перезапустить это задание в секундах:

public enum ScheduledTasks
{
    CleanGameRequests = 120,
    CleanUpOnlineUsers = 6
}

, а затем разбираюсь с ними на "Application_Start":

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        RegisterRoutes(RouteTable.Routes);

        // Adding the tasks i want at App_Start 
        // so if the application restarted my task will refreshed.
        AddTask(ScheduledTasks.CleanGameRequests);
        AddTask(ScheduledTasks.CleanUpOnlineUsers);
    }

    // event to handel
    private static CacheItemRemovedCallback _onCacheRemove;
    private void AddTask(ScheduledTasks task)
    {
        _onCacheRemove = new CacheItemRemovedCallback(CacheItemRemoved);
        HttpRuntime.Cache.Insert(task.ToString(), (int)task, null,
            DateTime.Now.AddSeconds((int)task), Cache.NoSlidingExpiration,
            CacheItemPriority.NotRemovable, _onCacheRemove);
    }

    public void CacheItemRemoved(string key, object time, CacheItemRemovedReason r)
    {
        var task = (ScheduledTasks)Enum.Parse(typeof(ScheduledTasks), key);
        switch (task)
        {
            case ScheduledTasks.CleanGameRequests:
                // Do the concept that you wanna to do.
                GameRequest.CleanUp();
                break;
            case ScheduledTasks.CleanUpOnlineUsers:
                OnlineUsers.CleanUp();
                break;
            default:
                break;
        }


        // Don't forget to recreate the "CacheItem" again.
        AddTask(task);
    }

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

В вашем случае вам следует проверить время до того, как воссоздать CacheItem снова.

Надеюсь, это помогло:)

1 голос
/ 09 июля 2011

Я делаю то же самое в своих веб-приложениях, но использую асинхронные обработчики HTTP (http://msdn.microsoft.com/en-us/library/ms227433.aspx#Y512); Я полагаю, что это будет рекомендовано. Я просто запускаю его при запуске приложения и выключаю его при завершении приложения (Global. ASX).

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

0 голосов
/ 09 июля 2011

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

Альтернативы:

  • просто сделайте это во время / сразу после запроса, который достаточно близок по времени
  • есть внешняя задача, которая будет запускать операцию на вашем сайте через GET / POST.
  • перенастроить IIS, чтобы никогда не перезапускать / останавливать пул приложений. Чем ваш таймер имеет шанс выполнить.
  • использовать некоторую внешнюю службу на сервере для планирования задачи («at» или даже задачи SQL).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...