Windows服务OnStop问题

本文关键字:问题 OnStop 服务 Windows | 更新日期: 2023-09-27 18:10:28

我有一个Windows服务,它是我从许多博客和论坛中收集来的,主要是我在这里问过的问题和回答。服务运行良好。唯一的问题是当我停止服务时;当我停止它时,我在日志文件中看到的是向下粘贴的内容。

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-04-23 14:53:01,062 [6] INFO GBBInvService。GBBInventoryService [(null)] - inside stop

2013-04-23 14:53:01,062 [6] INFO GBBInvService。GBBInventoryService [(null)] -未请求停止

它进入了(!_requestStop)而不是else。我的代码错了吗?有没有人能给我解释一下为什么它在(!_requestStop)里面,而不是在else语句里面。

任何建议将是非常感激的,因为我才刚刚开始动手操作Windows服务和最近的日志。

Windows服务OnStop问题

除非有什么东西改变了_requestStop,否则它将永远是假的。

ServiceBase没有代码自动将_requestStop设置为true,你的程序也不会在任何地方更改它。

您的代码正在正常运行。

OnStop()在Windows服务管理器请求停止时运行。详见http://msdn.microsoft.com/en-us/library/system.serviceprocess.servicebase.onstop.aspx

你可以设置

_requestStop = true 
在OnStop()顶部的

,以通知程序的其余部分完成任何任务。

也就是说,我不知道你想让这个程序做什么。

我可以就它应该做什么提供更多的细节。

根据您分享的代码,我认为有几件事正在发生:

  • 正如其他人指出的那样,没有_requestStop = true;的地方,!_requestStop将始终评估为true。那么OnStop()中的else就不可能执行了。将volatile添加到_requestStop的声明中,也许您希望操作系统修改它,但声明应该是public;即使这样,操作系统也不会自动修改_requestStop。所以,是的,关于_requestStop和期望else执行,你的代码似乎是错误的。
  • 你对_requestStop的使用似乎背叛了不信任,OnStop()只会在它应该被调用的时候被调用(即当停止被请求时)。作为Windows服务的新手,我想我可以看到这一点,但这种不信任是没有根据的。
  • 正如你所指出的,你是伐木新手,在我看来你是过度伐木了;有时候少就是多。

除非你没有共享使用_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();
    }
}

我不知道怎么了。你的逻辑永远不会改变_requestStop = true。总是假的。

!False肯定会通过if-true块