2016-09-22 9 views
0

Проблема: если БД находится в автономном режиме, когда эта служба запущена, эта служба не запускается, поскольку она не работает в этой строке: var container = new BootStrapper().Container; при запуске.Как запустить службу запуска Windows, если db отключен с помощью виндзора замка и объекта nhibernate?

private static void Main(string[] args) 
{ 
    Logger.Info("Engine Service is bootstrapping..."); 
    AppDomain.CurrentDomain.UnhandledException += UncaughtExceptions.DomainException; 
    Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory); 

    var container = new BootStrapper().Container; 
    var controller = container.Resolve<EngineController>(); 
    ServiceBase.Run(controller.MainView as ServiceBase); 

    container.Dispose(); 
} 

Причина она не существует, что он работает этот код, где он добавляет NHibernate объект container.AddFacility<NHibernateFacility>(); и терпит неудачу с тайм-аут соединения.

public void Install(IWindsorContainer container, IConfigurationStore store) 
{ 
    var isAutoTxFacilityRegistered = container.Kernel.GetFacilities().Any(f => f is AutoTxFacility); 
    if (!isAutoTxFacilityRegistered) container.AddFacility<AutoTxFacility>(); 

    container.Register(
     Component.For<INHibernateInstaller>().ImplementedBy<CieFluentInstaller>().IsDefault().LifestyleTransient(), 
     Classes.FromThisAssembly().Pick().WithService.DefaultInterfaces().LifestyleTransient() 
     ); 

    var isNHibernateFacilityRegistered = container.Kernel.GetFacilities().Any(f => f is NHibernateFacility); 
    if (!isNHibernateFacilityRegistered) container.AddFacility<NHibernateFacility>(); 
} 

Если служба окна запуска занимает больше времени, чем за 30 секунд (что он может, если обновление или резервные копии в настоящее время проводится на БД) сервис приложения не запускается.

Я использую FluentNhibernate, NHibernate, Castle Windsor с NHibernateFacility.

Что я пробовал:

  • Не может это сделать из события начала обслуживания, потому что он не до того, как получает представления или контроллер. Вид и контроллер не имеют прямого доступа к контейнеру IoC, только с помощью впрыскиваемого IoCFactory в соответствии с рекомендациями Castle Windsor.

  • Я пытался породить поток в основной и запустить его там с петля, повторная попытка, но потому, что служба «ждет» внутри метода ServiceBase.Run, я не могу показаться, чтобы получить правильный возвращается к , делая это «поддельным стартом» в цикле повтора.

  • исследуемых удлиняя начала тайм-аут службы, но не может получить доступ к ServiceBase/вида, так как он не до этого и вся системы изменения в сотнях производственных площадок не вариант.

Вопрос: Как я могу сделать это так, чтобы служба Windows «запускалась», когда БД отключена, учитывая дизайн?

ответ

0

Оказалось, что это ошибка в NHibernate, которая предотвратила выполнение любого из вышеперечисленных. Между Nibernate 2.0 и 3.0 необходимо добавить следующее в v3.0 NHibernate + конфигурации (или в данном случае FluentNHibernate):

cfg.SetProperty("hbm2ddl.keywords", "none"); 

Это позволяет NHibernate правильно усовершенствовать себя и получить к контроллеру теперь без ошибок ,

1

Вы должны разделить свои начальные действия на две категории:

  1. действия, которые должны произойти довольно немедленно и/или не исправить себя в случае неудачи. Такие вещи, как обязательный файл конфигурации , для которых потребуется вмешательство администратора.

  2. Действия, которые мы можем отложить, или, что более важно, - действия, которые могут привести к ошибке из-за временных ошибок. Такие ошибки могут быть сбоем в сети или что нам удалось запустить несколько быстрее, чем сервер базы данных после перезагрузки .

Вы служба OnStart код должен следовать этой базовой структуре:

OnStart: 
    Perform the immediate category 1 tasks and exit if any of these fail. 
    Launch the main application thread. 

Один из подходов к "основному потоку приложения", чтобы следовать этим основным структуру:

ManualResetEvent shutdownRequestedEvent = new ManualResetEvent() 

RealMain: 
    while (!shutdownRequestedEvent.WaitOne(0) && !bootstrapPerformed) 
    { 
     try 
     { 
      PerformBootstrap() 
      bootstrapPerformed = true 
     } 
     catch (Exception ex) 
     { 
      LogError(ex) 
     } 

     if (!bootstrapPerformed) 
      shutdownRequestedEvent.WaitOne(some timeout) 
    } 

    Second bootstrap action similar to above, etc. 

    Third bootstrap action similar to above, etc. 

    Eventually, start performing real work, while listening to 
    the shutdownRequestedEvent. 

Услуги OnShutdown будет сигнализировать shutdownRequestedEvent, а затем ждать выхода RealMain.

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

Еще одна вещь, о которой нужно помнить, - убедиться, что ваш сервис во время нормальной работы может выдержать временную потерю доступа к ресурсу из-за временных ошибок. Например, ваша служба не должна вылетать из строя только потому, что кто-то перезагружает сервер базы данных. Он должен просто терпеливо ждать и повторять навсегда.

Альтернативный подход, который может работать в некоторых случаях, заключается в том, чтобы обрабатывать загрузку как зависимость от любой реальной задачи. Например, запустив реальную задачу, реальная задача будет запрашивать сеанс базы данных, чтобы получить, что у нас должна быть фабрика сеансов, если у нас еще нет фабрики сеансов, запустите инициализацию фабрики сеансов. Если фабрика сеансов не может быть создана, исключение пузырится вверх и вся задача завершается с ошибкой. Остальная работа теперь должна подождать немного, а затем повторить задачу. Повторите навсегда.

+0

В то время как хорошая мысль, это не сработало лучше, чем мой второй маркер (они были очень похожи) из-за проблемы NHibernate, требующей «hbm2ddl.keywords» сначала установить «none». –

+0

Да, но моя структура имеет более широкие приложения. Например, службе, возможно, потребуется прочитать информацию из базы данных, прежде чем она сможет начать выполнять ее работу или начать прослушивание клиентских запросов. –

 Смежные вопросы

  • Нет связанных вопросов^_^