Повторяющиеся задачи в ASP .NET - PullRequest
4 голосов
/ 29 декабря 2011

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

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

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

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

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

Ответы [ 3 ]

5 голосов
/ 13 июня 2013

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

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

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

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

HostingEnvironment.RegisterObject(this);

Когда ASP.NET разрывает AppDomain, он сначалапопытка вызова метода 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

2 голосов
/ 29 мая 2018

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

0 голосов
/ 11 января 2012

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

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

...