2015-07-21 5 views
1

Я написал службу Windows, которая пытается читать сообщения из MSMQ и обрабатывать их. Я добавил установщика в свой проект, и я установил запуск вручную. Я устанавливаю службу, а затем запускаю ее через инструмент «Службы». Затем я могу вернуться к моему проекту и приложить к процессу переход через код.служба windows с использованием события выключения не удается остановить службу

Однако, независимо от того, что я делаю, я не могу остановить службу ни в коде, ни в инструменте Services. Я могу только думать, что это потому, что я использую класс ManualResetEvent для управления сервисом. Вот мой код. Я пытаюсь проверить раздел «Ошибка», так как в этот момент он должен выбросить ошибку и остановить службу.

В моем классе обслуживания у меня есть:

private readonly ManualResetEvent _shutdownEvent = new ManualResetEvent(false); 
    private Thread _thread; 

    public TestService() 
    { 
     InitializeComponent(); 
    } 

    protected override void OnStart(string[] args) 
    { 
     _thread = new Thread(WorkerThread) 
     { 
      Name = "Test Messaging Reader Service Thread", 
      IsBackground = true 
     }; 
     _thread.Start(); 

    } 

    protected override void OnStop() 
    { 
     _shutdownEvent.Set(); 
     if (!_thread.Join(3000)) 
     { // give the thread 3 seconds to stop 
      _thread.Abort(); 
     } 
     IError logger = new Logger(); 
     Exception ex = new Exception("The Test Messaging Service has been stopped."); 
     logger.Log(this, SeverityEnum.Warning, ex); 
    } 

    private void WorkerThread() 
    { 
     try 
     { 

      while (!_shutdownEvent.WaitOne(0)) 
      { 
       TestMessageQueueReader processQueue = new TestMessageQueueReader(); 
       processQueue.ReadFromQueue(); 
       _shutdownEvent.Set(); 
       _shutdownEvent.Reset(); 
      } 
     } 
     catch (Exception) 
     { 

      _shutdownEvent.Set(); 
      _shutdownEvent.Close(); 
     } 

    } 

Когда я пошагово код это делает падение в исключения, как и ожидалось, в какой момент я бы ожидать, чтобы быть в состоянии остановить службу.

ответ

1

Рабочий поток немедленно сбросить событие перед тестированием:

 while (!_shutdownEvent.WaitOne(0)) 
     { 
      // ... 
      _shutdownEvent.Reset(); 
     } 

Это означает, что если запрос остановки не приходит точно в нужное время, он будет проигнорирован.

Вместо этого, цикл должен выглядеть следующим образом:

 while (!_shutdownEvent.WaitOne(0)) 
     { 
      TestMessageQueueReader processQueue = new TestMessageQueueReader(); 
      processQueue.ReadFromQueue(); 
     } 

Вы также не должны закрывать события от рабочего потока, потому что другие потоки могут по-прежнему нуждается. (Событие будет автоматически закрыто, когда процесс завершится, поэтому вам не нужно беспокоиться об этом.)

Что касается обработки исключений, вы не можете отключить сервис, просто установив событие. Если есть более одного рабочего потока, установка события остановит их, но не сама служба. Я не совсем уверен, как вы делаете остановку службы .NET, но попробуйте позвонить ServiceBase.Stop.

+0

В конструкторе службы я установил CanStop = true; который определенно необходим, чтобы пользователь мог остановить службу из консоли управления. Сейчас этот бит работает. Однако, когда я спускаюсь по своему маршруту исключения, я хочу, чтобы служба остановилась, я удалил событие Reset() из цикла и в блоке Catch размещен _shutdownEvent.Set(); _shutdownEvent.Close(); и _shutdownEvent.Dispose(), но событие OnStop() не запускается. Я даже попробовал this.Stop(), но все еще не запускал OnStop Event :( – bilpor

+0

Хорошо, но не хорошо, но в событии OnStop, если я помещаю следующие 2 строки кода, тогда служба действительно останавливается. ExitCode = 0; Environment.Exit (Environment.ExitCode); – bilpor