Повторяющиеся задачи в ASP .NET

У меня есть веб-сайт ASP .NET, работающий на GoDaddy в общей среде. Приложение представляет собой услугу на основе подписки с возможностью регулярного выставления счетов пользователям.

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

Проблема: нам нужно создать фоновый поток, который запускает некоторый код с заранее определенным интервалом. Есть несколько хороших статей о фоновых задачах в .NET, но я уверен, что есть более простой способ обойти это. Может быть, таймер для всего приложения, который может вызывать функцию и т. Д.

Ограничение: общая среда не поддерживает службы Windows, внешние приложения, полное доверие и т. Д.

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


person Raheel Khan    schedule 29.12.2011    source источник
comment
проверьте это: stackoverflow.com/questions/1356789/quartz -нет-с-asp-net   -  person Davide Piras    schedule 29.12.2011
comment
Да, мне известно о Quartz. Я ищу индивидуальное решение, не зависящее от внешних лицензий, коммерческих или открытых.   -  person Raheel Khan    schedule 29.12.2011
comment
Как вы получаете данные от своего провайдера? Вы сказали, что нет механизма для вызова URL. Вы говорите, что они не могут позвонить вам, или вы не можете позвонить им, или и то, и другое?   -  person Burke Holland    schedule 30.12.2011
comment
Я имею в виду, что каждый раз, когда транзакция совершается с обработчиком платежей, они не уведомляют нас. Мы должны опросить их базу данных. Чтобы их опросить, нам нужна какая-то запланированная задача.   -  person Raheel Khan    schedule 05.01.2012


Ответы (3)


У меня была аналогичная проблема, я разрабатываю доказательство концепции ASP и использую фоновый поток, который выполняет задачу, которая может занять несколько часов. Проблема в том, что ASP.Net может повторно использовать AppDomain в любое время (убивая мой фоновый поток).

Чтобы предотвратить это, вы можете зарегистрировать свой фоновый поток в ASP.Net, чтобы он уведомлял ваш поток о завершении работы. Для этого реализуйте следующий интерфейс:

public interface IRegisteredObject
{
    void Stop(bool immediate);
}

И зарегистрируйте свой объект в ASP, используя следующий статический метод:

HostingEnvironment.RegisterObject(this);

Когда ASP.NET разрушает домен приложения, он сначала пытается вызвать метод Stop для всех зарегистрированных объектов. В большинстве случаев он вызывает этот метод дважды, один раз со значением false. Это дает вашему коду немного времени, чтобы завершить то, что он делает. ASP.NET дает всем экземплярам IRegisteredObject в общей сложности 30 секунд для завершения своей работы, а не 30 секунд каждому. По истечении этого промежутка времени, если остались какие-либо зарегистрированные объекты, он вызовет их снова с немедленным значением true.

Предотвращая возврат метода Stop (блокируя поле, когда рабочий занят), мы не позволяем ASP завершать работу AppDomain до тех пор, пока наша работа не будет завершена.

public void Stop(bool immediate)
{
    lock (_lock)
    {
        _shuttingDown = true;
    }
    HostingEnvironment.UnregisterObject(this); 
}

public void DoWork(Action work)
{
    lock (_lock)
    {
        if (_shuttingDown)
        {
            return;
        }
        work();
    }
}

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

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

Для получения дополнительной информации см. Мой источник: http://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in-asp-net.aspx

person Rob    schedule 13.06.2013
comment
На год позже, но решение мне нравится, и я попробую его в текущем проекте. Спасибо. - person Raheel Khan; 13.06.2013

Для обновления на 2018 год - пакет NuGet Hangfire идеально подходит для этого.

person niico    schedule 29.05.2018

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

Это ни в коем случае не идеальный подход, но для тех, кто может извлечь из этого выгоду, я создал задание cron для другой учетной записи хостинга Linux, нам пришлось вызвать требуемый URL-адрес ASP .NET. Менеджмент ужас, но свою работу делает.

person Raheel Khan    schedule 11.01.2012