Многопоточная служба Windows — Ninject Injected DbContext Injection Lifetime — лучшая практика?

В настоящее время я создаю службу Windows, которая создает поток, который запускается каждые 30 минут и обновляет несколько полей в некоторых объектах, которые соответствуют критериям (и в будущем я хочу добавить дополнительные потоки, чтобы делать другие вещи, например запускать по одному каждые 24 часа, один раз в неделю и т.д.). Служба будет получать и обновлять свои данные с помощью служб, которые уже используются веб-приложением и внедряются с помощью Ninject (вместе с DbContext) — все это отлично работает с использованием привязки InRequestScope().

Однако я думал о том, как лучше всего подойти к этому с помощью службы Windows. По сути, после запуска службы и создания потока она работает непрерывно (кроме перехода в спящий режим каждые 30 минут) и останавливается только в том случае, если служба Windows останавливается или процесс завершается. Моя первоначальная мысль заключалась в том, чтобы внедрить мой DbContext и службы, используя параметр InThreadScope() Ninject, поэтому у меня был бы DbContext для каждого потока. Но является ли хорошей практикой использование DbContext с таким длительным временем жизни? Этот DbContext может сидеть там неделями и не быть утилизированным, и у меня есть подозрение, что это не такая уж хорошая идея (утечка памяти и т. д.).

Но если нет, то как лучше всего справиться с этим сценарием. Я мог бы создавать новый DbContext каждый раз, когда запускается поток, но как мне настроить привязки Ninject? В настоящее время они определяются как:

        Bind<IDbContext>().To<EnterpriseDbContext>().InThreadScope();
        Bind<IUserRepository>().To<UserRepository>().InThreadScope();
        // Etc

Поэтому я не совсем уверен, как бы я структурировал это, чтобы создать новый в потоке. Я посмотрел на InTransientScope(), но из-за этого мои службы используют разные версии контекста, поэтому мои изменения никогда не сохраняются.

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


person stevehayter    schedule 06.09.2013    source источник


Ответы (2)


Вместо создания потоков, которые спят до следующего запуска, вы можете использовать Quartz.Net в качестве механизма планирования. В сочетании с InCallScope из расширения NamedScope у вас такое же поведение, как InRequestScope WebService. Кроме того, вы получаете более эффективное планирование, чем просто создание потоков, которые выполняются с интервалами. Вы можете указать, когда они должны запускаться, используя синтаксис Cron Job.

Видеть:

person Remo Gloor    schedule 06.09.2013
comment
Интересные предложения @Remo - мне особенно нравится внешний вид Quartz. Кривая обучения для этого выглядит немного необходимой на данный момент, так как у меня короткий срок, но это то, на что я обязательно рассмотрю в будущем. - person stevehayter; 08.09.2013

Мне особенно нравятся предложения @Remo, и я попробую их в следующем проекте, над которым работаю. Однако в конце концов я решил проблему, используя собственную реализацию InScope, но задав пользовательский объект, область действия которого должна быть при каждом запуске потока. Таким образом, контекст воссоздавался каждый раз, когда он запускался (как он был удален после удаления объекта области видимости).

person stevehayter    schedule 08.09.2013