Windows服务OnStop问题

时间:2013-04-23 03:00:50

标签: c# .net service windows-services

我有一个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)] - 内部停止

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

它位于(!_requestStop)内,而不是else。我的代码错了吗?有人能够向我解释为什么它会进入(!_requestStop)而不是else语句。

我非常感谢任何建议,因为我刚开始接受Windows服务和最近的日志记录。

3 个答案:

答案 0 :(得分:7)

除非某些内容发生变化_requestStop,否则它将始终为false。

ServiceBase没有将自动将_requestStop设置为true的代码,并且您的程序无法在任何地方进行更改。

您的代码按预期运行。

当Windows服务管理器停止REQUEST时,将运行OnStop()。请点击http://msdn.microsoft.com/en-us/library/system.serviceprocess.servicebase.onstop.aspx

了解更多信息

你要设置

_requestStop = true 

在OnStop()的顶部,向程序的其余部分发出信号以完成任何任务。

那就是说,我不知道你希望这个程序做什么。我可以进一步提供更多细节,告诉他们应该做些什么。

答案 1 :(得分:2)

根据您分享的代码,我认为有一些事情正在发生:

  • 正如其他人所指出的那样,_requestStop = true;在某个地方没有!_requestStop,总是会评估为true。那么else中的OnStop()将无法执行。将volatile添加到_requestStop的声明中,也许您希望操作系统对其进行修改,但声明应为public;即便如此,操作系统也不会自动修改_requestStop。所以,是的,关于_requestStop并期望else执行,你的代码似乎错了。
  • 您对_requestStop的使用似乎背叛了不信任,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();
    }
}

答案 2 :(得分:1)

我没有看到什么是错的。你的逻辑永远不会改变_requestStop = true。它总是错误的。

!false肯定会经过if-true block。