Я пытаюсь выполнить Scheduled Job
System.Threading
с использованием System.Threading
.
Мой код работает в первый раз правильно и сохраняет журнал в базе данных, но таймер не перезвон после временного интервала.
Я следую примеру на ссылке [пример] http://dhavalupadhyaya.wordpress.com/2008/08/30/how-to-create-scheduled-jobs-in-net-web-applications/
Моя реализация такова:
public sealed class Jobs
{
public Jobs() { }
public static void HourlyJob(object state)
{
SchedularDBContext schedular = new SchedularDBContext();
DBSchedulars dbSchedular = new DBSchedulars();
dbSchedular.Message = "Generated time span = " + DateTime.Now.ToString();
schedular.DbSchedulars.Add(dbSchedular);
schedular.SaveChanges();
}
}
public sealed class Schedular
{
public Schedular() { }
public void Schedular_Start()
{
TimerCallback callbackHourly = new TimerCallback(Jobs.HourlyJob);
Timer hourlytimer = new Timer(callbackHourly, null, TimeSpan.Zero,TimeSpan.FromMinutes(1.0));
}
}
Я называю это в global.ascx как
protected void Application_Start(object sender, EventArgs e)
{
CodeFiles.Schedular objSchedular = new CodeFiles.Schedular();
objSchedular.Schedular_Start();
}
Но таймер запускается в первый раз после того, как он не работает. Я хочу, чтобы он работал каждую минуту. Что в этом плохого? И как я могу заставить его запускать каждую минуту автоматически?
Вы столкнулись с проблемой утилизации таймера - ваш objSchedular
не ссылается нигде после выполнения Application_Start
а также внутри вашего экземпляра Schedular
не содержит ссылки на объект.NET Timer
. Поэтому сборщик мусора видит ваши объекты как мусор, потому что ссылки на эти объекты не найдены, поэтому таймер расположен во время цикла GC.
Я бы рекомендовал прочитать Richter CLR через С# "Коллекции мусора и отладки", где он показывает эту ошибку с объектом Timer. Поэтому храните ссылку на свой objSchedular
как поле, а внутри него хранится переменная hourlytimer
как поле, и это устранит вашу проблему.
Быстрый ответ заключается в том, что вам нужно сделать свой объект статическим и объявить его где-то еще, а не внутри запуска приложения. При запуске приложения вам нужно только вызвать objSchedular.Schedular_Start();
CodeFiles.Schedular static objSchedular = new CodeFiles.Schedular();
Его все о сохранении области действия объекта Timer
2 варианта
Пропустить объект Timer
к конструктору класса " Shceduler
" и использовать его
Если вам нужно создать много объектов Timer
в классе " Shceduler
", создайте List<Timer>
и передайте его конструктору класса Scheduler. Добавить новый объект Timer
в этот список. Но не забудьте освободить таймеры из списка, как только они вам не нужны.