【问题标题】:Windows service OnStop issueWindows 服务 OnStop 问题
【发布时间】:2013-04-23 03:00:49
【问题描述】:

我有一个 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 服务和最近的日志记录。

【问题讨论】:

    标签: c# .net service windows-services


    【解决方案1】:

    除非某些东西改变了_requestStop,否则它总是假的。

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

    您的代码正在按预期运行。

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

    你会设置

    _requestStop = true 
    

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

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

    【讨论】:

      【解决方案2】:

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

      • 正如其他人指出的那样,如果没有 _requestStop = true; 某处,!_requestStop 将始终评估为 true。那么OnStop() 中的else 不可能执行。将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();
          }
      }
      

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-10-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多