Планировщик Quartz.net не остается в живых

1

Прочитав некоторые 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(), если я могу его избежать, так как когда я использую этот планировщик в другом месте, я не хочу, чтобы он сидел там в этом состоянии. Будет ли подключение слушателя помешать ему умереть?

Теги:
unit-testing
quartz.net

2 ответа

3
Лучший ответ

Ваш планировщик отключается, потому что тест заканчивается, и мусор собирает все. Если вы действительно хотели дать время планировщика для завершения своей работы, вам нужно будет найти способ проведения теста, добавив оператор Thread.Sleep сразу после Scheduler.Start(); метод.

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

  • 0
    Я так и думал. Я использовал Thread.Sleep после того, как опубликовал вопрос, и он работает, так как я делаю некоторое время jobcount> 0 spin. Я согласен с макетом, я сделаю это для модульного тестирования. Что касается смерти планировщика в том виде, в каком он у меня есть сейчас, я попытался смоделировать его так, как он будет в действительности использоваться. Означает ли это, что мне все еще нужно разобраться с этим с помощью Thread.Sleep или чего-то подобного?
  • 1
    «в реальном мире» вы либо запускаете планировщик как отдельную службу Windows, и в этом случае планировщик останется живым. ИЛИ вы бы встроили его в свое приложение, и в этом случае, если вы создадите его как одноэлементное приложение, все будет в порядке, пока ваше приложение не будет закрыто.
Показать ещё 3 комментария
0

Поработав с более ранней версией кварца, я помню, что планировщик запускает задание в потоке (или более). Это может быть то, что вы потом испытываете. Так что, возможно, вам следует протестировать, используя другой подход.

С уважением, Франк

  • 0
    Документы говорят, что он идет на обычном ThreadPool, но не указывает, является ли он потоком переднего плана / фона. Я предполагаю фоновый поток, потому что приложение не остается в живых?
  • 0
    Так или иначе, я бы выполнил Integration Test, запустив задание с использованием планировщика, но проверил вывод / результат ожидаемого запуска задания, то есть вам нужно было бы выполнить Thread.Sleep

Ещё вопросы

Сообщество Overcoder
Наверх
Меню