0

我有一个 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] 信息 GBBInvService.GBBInventoryService [(null)] – 未请求停止

它进入内部(!_requestStop)而不是else. 我的代码错了吗?有人可以向我解释为什么它会进入(!_requestStop)而不是 else 语句。

任何建议都将不胜感激,因为我才刚刚开始亲身体验 Windows 服务和最近的日志记录。

4

3 回答 3

7

除非有什么改变 _requestStop,否则它总是假的。

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

您的代码按预期运行。

当从 Windows 服务管理器请求停止时运行 OnStop()。在http://msdn.microsoft.com/en-us/library/system.serviceprocess.servicebase.onstop.aspx查看更多信息

你会设置

_requestStop = true 

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

也就是说,我不知道你想让这个程序做什么。我可以就它应该做什么提供更多详细信息。

于 2013-04-30T22:07:21.947 回答
2

根据您共享的代码,我认为发生了一些事情:

  • 正如其他人指出的那样,没有_requestStop = true;地方,!_requestStop总是会评估为true。那么elseinOnStop()就不可能执行了。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();
    }
}
于 2013-05-05T16:44:43.743 回答
1

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

!false 肯定会通过 if-true 块。

于 2013-04-23T03:05:28.050 回答