Прочитав некоторые SO Q & A, я беру рекомендованный подход НЕ писать собственный планировщик. Я решил использовать Quartz.net, так как он хочет сделать именно то, что мне нужно. Согласно их краткому руководству по началу работы приложение не должно закрываться после создания экземпляра планировщика до тех пор, пока я не вызову метод shutdown в планировщике: http://www.quartz-scheduler.net/documentation/quartz-2.x/quick- start.html
Я тестирую это в модульном тесте, и я обнаружил, что мой тест nUnit закрывается без того, чтобы я вызывал выключение планировщика! Я сделал планировщик синглтон, предполагая, что это исправит, но такой удачи не было. Является ли это поведение специфичным для модульного тестирования? Я предполагаю, что, поскольку это происходит в моих тестах, это произойдет, когда я буду использовать его в своем консольном приложении позже.
Вот как я собрал свой планировщик:
public static class Scheduler
{
public static IScheduler LocalScheduler { get; private set; }
static Scheduler()
{
// get a scheduler
ISchedulerFactory schedFact = new StdSchedulerFactory();
LocalScheduler = schedFact.GetScheduler();
}
public static void ScheduleJob(IJobDetail job, ITrigger trigger)
{
LocalScheduler.ScheduleJob(job, trigger);
}
public static void Start()
{
if (!LocalScheduler.IsStarted) LocalScheduler.Start();
}
public static void Stop()
{
LocalScheduler.Shutdown();
}
}
Единичный тест, в частности, не работает:
[Test, Explicit]
public void JobExecutionTest()
{
var start = new DateTime(2014,06,01);
var stop = new DateTime(2014,06,10);
// I made my own factories for the JobDataMap, IJobDetail, and ITrigger.
var jobMap = JobDataFactory.CreateConnectwiseMap(start, stop);
var job = JobFactory.CreateParameterJob<ConnectwiseJob>("testjob", "testgroup", jobMap);
// fire in 5 seconds for testing
var trigger = TriggerFactory.CreateRecurring("testtrigger", "testgroup", DateTime.Now.AddSeconds(5));
Scheduler.ScheduleJob(job, trigger);
Scheduler.Start();
// it shuts down almost immediately!
}
Я поставил точку останова в задании, которое должно выполняться, чтобы увидеть, если он когда-либо попал, и он никогда не делает этого, потому что unit тест считает, что все это сделано и закрывает все. Я не хочу использовать Thread.Sleep(), если я могу его избежать, так как когда я использую этот планировщик в другом месте, я не хочу, чтобы он сидел там в этом состоянии. Будет ли подключение слушателя помешать ему умереть?
Ваш планировщик отключается, потому что тест заканчивается, и мусор собирает все. Если вы действительно хотели дать время планировщика для завершения своей работы, вам нужно будет найти способ проведения теста, добавив оператор Thread.Sleep сразу после Scheduler.Start(); метод.
Тем не менее, вы действительно не хотите тестировать свои вакансии таким образом, хотя. Вы должны высмеять IJobExecutionContext и передать его в свою работу для выполнения.
Поработав с более ранней версией кварца, я помню, что планировщик запускает задание в потоке (или более). Это может быть то, что вы потом испытываете. Так что, возможно, вам следует протестировать, используя другой подход.
С уважением, Франк