简体   繁体   English

Windows服务OnStop问题

[英]Windows service OnStop issue

I have a Windows service which I put together from a number of blogs and forums, mainly questions I've asked and had answered here. 我有一个Windows服务,该服务是由许多博客和论坛汇集而成的,主要是我在这里提出和回答的问题。 The service works fine. 该服务工作正常。 The only problem is when I stop the service; 唯一的问题是我何时停止服务? pasted further down is what I see in the log files when I stop it. 停止粘贴时,我在日志文件中看到的是粘贴的内容。

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();
    }
}

The service stops properly and starts again fine, but I don't know if my code is wrong because the log file is showing: 该服务正常停止并再次正常启动,但是我不知道我的代码是否错误,因为日志文件正在显示:

2013-04-23 14:53:01,062 [6] INFO GBBInvService.GBBInventoryService [(null)] – inside stop 2013-04-23 14:53:01,062 [6]信息GBBInvService.GBBInventoryService [(null)] –内部停止

2013-04-23 14:53:01,062 [6] INFO GBBInvService.GBBInventoryService [(null)] – Stop not requested 2013-04-23 14:53:01,062 [6] INFO GBBInvService.GBBInventoryService [(null)] –不要求停止

It's going inside of (!_requestStop) instead of the else . 它在(!_requestStop)而不是else Is my code wrong? 我的代码错了吗? Would somebody be able to explain to me why it is going inside of (!_requestStop) instead of the else statement. 有人可以向我解释为什么它在(!_requestStop)而不是else语句内。

Any advise would be greatly appreciated, as I've only just started getting a hands-on of Windows services and most recently logging. 任何建议将不胜感激,因为我才刚刚开始动手使用Windows服务和最近的日志记录。

Unless something changes _requestStop, it will always be false. 除非_requestStop发生更改,否则它将始终为false。

ServiceBase has no code that will automagically set _requestStop to true, and your program doesn't change it any where. ServiceBase没有代码可以自动将_requestStop设置为true,并且您的程序不会在任何地方对其进行更改。

Your code is running as expected. 您的代码正在按预期运行。

OnStop() is ran when a stop is REQUEST from the Windows Service Manager. 从Windows服务管理器请求停止时,将运行OnStop()。 See more at http://msdn.microsoft.com/en-us/library/system.serviceprocess.servicebase.onstop.aspx 请参阅http://msdn.microsoft.com/zh-cn/library/system.serviceprocess.servicebase.onstop.aspx

You would set 你会设置

_requestStop = true 

at the top of OnStop() to signal to the rest of the program to finish any tasks. 在OnStop()的顶部以向程序的其余部分发出信号以完成所有任务。

That said, I don't know what you want this program to do. 就是说,我不知道您希望该程序做什么。 I can advise further with more details as to what it's supposed to be doing. 我可以提供更多有关它应该做什么的更多详细信息。

Based on the code you have shared, I think there are a few things going on: 根据您共享的代码,我认为发生了一些事情:

  • As others have pointed out, without _requestStop = true; 正如其他人指出的那样,如果没有_requestStop = true; somewhere, !_requestStop will always evaluate to true . 在某处, !_requestStop始终将评估为true There is no possibility then that the else in OnStop() will execute. 这样就不可能执行OnStop()中的else With volatile added to _requestStop 's declaration, maybe you expected the OS to modify it, but the declaration should then be public ; 随着volatile添加到_requestStop的声明,也许你期待的操作系统进行修改,但随后的声明应该public ; and even then the OS is not going to automagically modify _requestStop . 即使这样,操作系统也不会自动修改_requestStop So, yes, with respect to _requestStop and expecting the else to ever execute, your code seems wrong. 因此,是的,对于_requestStop并期望else能够执行,您的代码似乎是错误的。
  • Your use of _requestStop seems to betray mistrust that OnStop() will only be called when it should be called (ie when a stop has been requested). 您对_requestStop使用似乎表明,您不信任OnStop()仅在应调用OnStop()时才被调用(即,当请求停止时)。 Being new to Windows services, I guess I could see that, but such mistrust is unwarranted. 我想我是Windows服务的新手,但是这种不信任是没有必要的。
  • Being new to logging as you point out, you are over-logging IMO; 正如您所指出的,对于日志记录来说是新手,因此您正在过度记录IMO。 sometimes less is more. 有时少即是多。

Unless code you have not shared uses _requestStop , here are the changes I would suggest for the specific issue and questions you raised about your code: 除非您尚未共享的代码使用_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();
    }
}

i don't see what's wrong. 我看不出有什么问题。 your logic never change _requestStop = true. 您的逻辑永远不会改变_requestStop = true。 it's always false. 总是错误的。

!false definitely will go through if-true block. !false肯定会经过if-true块。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM