2013-04-23 100 views
0

我有一個Windows服務,我放在一起從衆多博客和論壇上的,主要是我提出的問題,並在這裏找到答案。該服務工作正常。唯一的問題是當我停止服務時,粘貼進一步是我在停止日誌文件時看到的內容。Windows服務調用OnStop問題

public partial class GBBInvService : ServiceBase 
{ 
    private static readonly ILog log = LogManager.GetLogger(typeof(GBBInvService)); 
    System.Timers.Timer timer = new System.Timers.Timer(); 
    private volatile bool _requestStop=false; 
    private ManualResetEventSlim resetEvent = new ManualResetEventSlim(false); 


    public GBBInvService() 
    { 
     InitializeComponent(); 
    } 

    protected override void OnStart(string[] args) 
    { 
     _requestStop = false; 
     timer.Elapsed += new ElapsedEventHandler(timer_Elapsed); 
     timer.Interval = 18000; 
     timer.Enabled = true; 
     timer.Start(); 
     log.Info("GBBInvService Service Started"); 
    } 

    protected override void OnStop() 
    { 
     log.Info("inside stop"); 
     if (!_requestStop) 
     { 
      log.Info("Stop not requested"); 
      timer.Start(); 
     }  
     else 
     { 
      log.Info("On Stop Called"); 
      WaitUntilProcessCompleted(); 
     } 
    } 

    private void timer_Elapsed(object sender, ElapsedEventArgs e) 
    { 
     log.Info("Timer elapsed at " + Convert.ToString(e.SignalTime)); 
     InvProcessing(); 
    } 

    private void InvProcessing() 
    { 
     try 
     { 
      resetEvent.Reset(); 
      //*Processing here* 
     } 
     catch (Exception ex) 
     { 
      resetEvent.Set(); 
      log.Error(ex.Message); 
     } 
    } 


    private void WaitUntilProcessCompleted() 
    { 
     resetEvent.Wait(); 
    } 
} 

服務正常停止並再次開始很好,但我不知道是否我的代碼是錯誤的,因爲日誌文件顯示:

2013年4月23日14:53:01062 [ 6] INFO GBBInvService.GBBInventoryService [(空)] - 內停止

2013年4月23日14:53:01062 [6] INFO GBBInvService.GBBInventoryService [(空)] - 停止未請求

這是怎麼回事的(!_requestStop)內,而不是else的。我的代碼錯了嗎?有人能夠向我解釋爲什麼它會進入(!_requestStop)而不是else語句。

任何意見,將不勝感激,因爲我只是剛剛開始獲得Windows服務和最近日誌記錄的動手。

回答

2

根據您所共享的代碼,我認爲有幾件事情怎麼回事:

  • 正如其他人所指出的那樣,沒有_requestStop = true;地方,!_requestStop將始終評估爲true。那麼OnStop()中的else將不會執行。隨着volatile加入_requestStop的聲明,也許你期待的操作系統進行修改,但隨後的聲明應該是public;即使這樣操作系統也不會自動修改_requestStop。所以,是的,關於_requestStop和期待else永遠執行,你的代碼似乎是錯誤的。
  • 您對_requestStop的使用似乎背叛了OnStop()僅在應該調用OnStop()時纔會被調用(即,當已請求停止時)。作爲Windows服務新手,我想我可以看到,但這種不信任是沒有根據的。
  • 正如您所指出的那樣,您正在嘗試記錄日誌,您正在過度記錄IMO;有時更少更多。

除非你沒有共享代碼使用_requestStop,這裏的變化我會建議你提出你的代碼的具體問題和疑問:

public partial class GBBInvService : ServiceBase 
{ 
    private static readonly ILog log = LogManager.GetLogger(typeof(GBBInvService)); 
    System.Timers.Timer timer = new System.Timers.Timer(); 
    //private volatile bool _requestStop=false; // no _requestStop 
    private ManualResetEventSlim resetEvent = new ManualResetEventSlim(false); 


    public GBBInvService() 
    { 
     InitializeComponent(); 
    } 

    protected override void OnStart(string[] args) 
    { 
     //_requestStop = false; 
     timer.Elapsed += new ElapsedEventHandler(timer_Elapsed); 
     timer.Interval = 18000; 
     timer.Enabled = true; 
     timer.Start(); 
     log.Info("GBBInvService Service Started"); 
    } 

    protected override void OnStop() 
    { 
     //log.Info("inside stop"); 
     //if (!_requestStop) 
     //{ 
     // log.Info("Stop not requested"); 
     // timer.Start(); 
     //}  
     //else 
     //{ 
     // log.Info("On Stop Called"); 
     // WaitUntilProcessCompleted(); 
     //} 

     WaitUntilProcessingCompleted(); 
     log.Info("GBBInvService Service Stopped"); 
    } 

    private void timer_Elapsed(object sender, ElapsedEventArgs e) 
    { 
     log.Info("Timer elapsed at " + Convert.ToString(e.SignalTime)); 
     InvProcessing(); 
    } 

    private void InvProcessing() 
    { 
     try 
     { 
      resetEvent.Reset(); 
      //*Processing here* 

     } 
     catch (Exception ex) 
     { 
      log.Error(ex.Message); 
     } 
     finally 
     { 
      resetEvent.Set(); 
     } 
    } 


    private void WaitUntilProcessCompleted() 
    { 
     resetEvent.Wait(); 
    } 
} 
1

我看不出有什麼不對。你的邏輯永遠不會改變_requestStop = true。它總是假的。

!false肯定會經過if-true塊。

+0

所以我的代碼是正確的? – user1270384 2013-04-23 03:21:20

7

除非有什麼更改_requestStop,它將始終是錯誤的。

ServiceBase沒有代碼會自動將_requestStop設置爲true,並且您的程序不會在任何地方更改它。如預期

你的代碼運行。

從Windows服務管理器請求停止時會運行OnStop()。多見於http://msdn.microsoft.com/en-us/library/system.serviceprocess.servicebase.onstop.aspx

您需要將

_requestStop = true 

在調用OnStop()的頂部信號的程序完成任何任務的其餘部分。

這就是說,我不知道你想要這個程序做什麼。我可以進一步提供更多關於它應該做什麼的細節。

+1

+1這是我會回答的。 – 2013-05-04 02:56:01