2014-02-10 160 views
0

在啓動Windows服務時遇到此錯誤消息時仍然保留。Windows服務不斷啓動和停止

本地計算機上的服務啓動,然後停止。某些服務如果未被其他服務和程序使用,則會自動停止。

我的代碼:

 protected override void OnStart(string[] args) 
    { 
     string eventLogMessage = string.Format(@"Notify Service is starting :{0}", DateTime.Now); 
     EventLogging.LogInformation(eventLogMessage); 

      double interval; 

      try 
      { 
       interval = Convert.ToDouble(ConfigurationManager.AppSettings["intervalInSeconds"]); 
       EventLogging.LogInformation(
        string.Format("Loaded configuration: Interval duration is {0} minutes", (interval/60))); 
      } 
      catch (Exception exception) 
      { 
       interval = 3600; 

       eventLogMessage = string.Format("Loading configuration failed: Interval duration is {0} minutes", (interval/60)); 
       eventLogMessage += string.Format("\nMessage was: {0}", exception.Message); 

       EventLogging.LogWarning(eventLogMessage); 
      } 

      interval = interval * 1000; 

      _timer.Interval = interval; 
      _timer.Elapsed += TimerTick; 
      _timer.Start(); 

      eventLogMessage = string.Format(@"Notify service has started: {0}", DateTime.Now); 
      EventLogging.LogInformation(eventLogMessage); 

      var workerThread = new Thread(NotifyUsers) { IsBackground = true }; 
      workerThread.Start(); 

    } 

    private void NotifyUsers() 
    { 
     var userBL = new UserBL(); 

     List<User> usersToBeMailed = userBL.GetAllUsersWhosePasswordsWillExpire(); 

     string eventLogMessage = string.Format("Number of users to be mailed is {0}", usersToBeMailed.Count); 
     EventLogging.LogInformation(eventLogMessage); 

     foreach (User user in usersToBeMailed) 
     { 
      userBL.MailUser(user); 
     } 
    } 

    private void TimerTick(object sender, ElapsedEventArgs e) 
    { 
     var workerThread = new Thread(NotifyUsers) { IsBackground = true }; 
     workerThread.Start(); 
    } 

    protected override void OnStop() 
    { 
     base.OnStop(); 

     string eventLogMessage = @"Password notify service has stopped: " + DateTime.Now; 

     EventLogging.LogInformation(eventLogMessage); 
    } 


    protected override void OnPause() 
    { 
     base.OnPause(); 
     _timer.Stop(); 
     EventLogging.LogWarning("Paused"); 
    } 

    protected override void OnContinue() 
    { 
     base.OnContinue(); 
     _timer.Start(); 
     EventLogging.LogInformation("Resumed"); 
    } 
} 
+0

有什麼可在'OnStart' \'OnStop'方法去相當嚴格的規定。我在猜'workerThread'代碼。作爲一個測試嘗試刪除,看看它是否仍然停止。 – cjb110

+0

也將_timer和worker移至單獨的「初始化」方法。 'OnStart'應該很簡單,具有完整的異常處理。 – cjb110

+0

嘗試調試器附加到服務,以尋找到異常發生,在中的OnStart()方法的第一行中加入了Thread.Sleep(30000),這樣你可以有一段代碼執行完之前連接調試程序。在Thread.Sleep調用之後不要忘記一個斷點,以便在線程喚醒時可以逐行手動調試。 –

回答

0

你必須有你的線程做的事情,而不是作爲一個後臺線程的至少一個,以保持工藝活。該OnStart代碼運行在該線程是不是真的是你的一個線程,而且,你必須從OnStart爲了返回被認爲已經成功啓動。

這可能是因爲創建和從OnStart方法,只是等待一個ManualResetEvent對象上運行的新Thread一樣簡單,你SetOnStop代碼。

或者,找到一些有用的工作,爲這個線程做(但仍使用事件對象發出信號時,應關閉),或替代二是 - 考慮下面的代碼是否在服務屬於可言。如果它只是週期性地醒來以通知用戶,爲什麼不使用計劃任務呢?