Windows 服务运行但在两天后停止处理

Windows Service runs but stops processing after two days

我看过很多关于这个问题的帖子,但似乎没有一个符合我的标准。

话虽如此,这是我构建的第一个 "needs" 来执行大量逻辑。这几天一切正常,但之后逻辑停止工作,没有登录事件查看器,也没有发送电子邮件(例外)。

我在想是不是我的逻辑不对...求指点。

public partial class QuayService : ServiceBase
{
    private System.Timers.Timer m_mainTimer;
    private bool m_timerTaskSuccess;
    private Email _email;
    public QuayService()
    {
        InitializeComponent();
        _email = new Email();
    }

    protected override void OnStart(string[] args)
    {
        try
        {
            // Create and start a timer.
            m_mainTimer = new System.Timers.Timer();
            m_mainTimer.Interval = 5000;   // every 5 seconds
            m_mainTimer.Elapsed += m_mainTimer_Elapsed;
            m_mainTimer.AutoReset = false;  // makes it fire only once
            m_mainTimer.Start(); // Start

            m_timerTaskSuccess = false;

            _email.SendEmail("Quay", "(Shopify)Quay Service Started",
                "(Shopify)Quay Service Successfuly Started");

            EventLog.WriteEntry("(Shopify)Quay Service Started...");
        }
        catch (Exception ex)
        {
            // Log/Send Email
            _email.SendEmail("Quay", "Error starting (Shopify)Quay Service", ex.Message + " " + 
                ex.InnerException.Message);

            EventLog.WriteEntry("Error starting (Shopify)Quay service and timer..." + ex.Message + " " +
                ex.InnerException.Message);
        }
    }

    protected override void OnStop()
    {
        try
        {
            // Service stopped. Also stop the timer.
            m_mainTimer.Stop();
            m_mainTimer.Dispose();
            m_mainTimer = null;

            _email.SendEmail("Quay", "(Shopify)Quay Service stopped",
                "(Shopify)Quay Service Successfuly Stopped");

            EventLog.WriteEntry("(Shopify)Quay Service stopped...");
        }
        catch (Exception ex)
        {
            _email.SendEmail("Quay", "Error stopping (Shopify)Quay Service", ex.Message + " " +
                ex.InnerException.Message);

            // Log/Send Email
            EventLog.WriteEntry("Error stopping (Shopify)Quay timer and service..." + ex.Message + " " +
                ex.InnerException.Message);
        }
    }

    void m_mainTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        try
        {
            var orderUoW = new OrderUoW();
            orderUoW.Create();

            m_timerTaskSuccess = true;
        }
        catch (Exception ex)
        {
            //Error with timer elapsed
            m_timerTaskSuccess = false;

            _email.SendEmail("Quay", "Error creating (Shopify)Quay order(s)", ex.Message + " " +
                ex.InnerException.Message);

            EventLog.WriteEntry("Error creating (Shopify)Quay order(Time elapsed event)..." + ex.Message
                + " " + ex.InnerException.Message);
        }
        finally
        {
            if (m_timerTaskSuccess)
            {
                m_mainTimer.Start();
            }
        }
    }
}

为了达到这一点,我 "googled" 和 "SO'ed" 找到了计时器的最佳用途...我还有一个简单的测试层,可以重现服务中的内容,我可以 运行 毫无例外地通过那次罚款,但这一次让我发疯。

非常感谢任何帮助!

//编辑

一点解释:

var orderUoW = new OrderUoW(); 
orderUoW.Create();

OrderUoW 是我服务中的一个 class,它继承自 BatchOrder,它负责许多操作,包括连接到两个数据库和轮询 shopify API。 .. OrderUow 纯粹是为了与业务层分离,但可以访问 "x" 方法。

两天内一切正常,但似乎停止了。我没有达到 shopify 中的请求限制...所以目前,我不知所措。

在对 MS Timer Bug.MS Timer Bug.

挠头和极度烦恼之后

不仅吞下了异常,定时器也没有引发事件!我的服务挂了,这特别难,因为它还吞下了异常。

现在我确实走上了 Threading.Timer

的一半实施路线
  1. 不要使用System.Windows.Forms.Timer因为它不起作用(这才有意义)。

  2. 不要使用System.Threading.Timer,因为它不起作用,请改用System.Timers.Timer。

  3. 不要使用System.Timers.Timer,因为它不起作用,请改用System.Threading.Timer。

Related question.

我真的不会为这些步骤带来的问题而烦恼,因为我的目标是专注于业务逻辑。所以我决定使用 Quartz.Net.

它让我的生活变得轻松多了,而且似乎工作得很好! 45-60 分钟的工作。

基本设置:

1,Nuget > 石英

2,新建文件夹 > QuartzComponents > 作业和计划

3、在各自的文件夹中添加了OrderJob.csOrderJobSchedule.cs

OrderJob.cs逻辑:

 public sealed class OrderJob : IJob
 {
    public void Execute(IJobExecutionContext context)
    {
            var orderUoW = new OrderUoW();
            orderUoW.Create();
     }
  }

注意到它创建了我的 UoW 实例?!?每次传球都会命中的逻辑。

OrderJobSchedule.cs逻辑:

   public sealed class OrderJobSchedule
    {
        public void Start()
        {
            IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler();
            scheduler.Start();

            IJobDetail job = JobBuilder.Create<OrderJob>().Build();

            ITrigger trigger = TriggerBuilder.Create()
                   .WithSimpleSchedule(a => a.WithIntervalInSeconds(15).RepeatForever())
                   .Build();

            scheduler.ScheduleJob(job, trigger);
        }

        public void Stop()
        {
            IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler();
            scheduler.Shutdown();
        }
    }

这里有很多魔法,但要强调:

JobBuilder.Create<OrderJob>().Build();

a.WithIntervalInSeconds(15).RepeatForever()

现在我们需要向服务的 "guts" 添加逻辑:

public partial class QuayService : ServiceBase
    {
        OrderJobSchedule scheduler;
        public QuayService()
        {
            InitializeComponent();
        }
        protected override void OnStart(string[] args)
        {
            try
            {
                scheduler = new OrderJobSchedule();
                scheduler.Start();

                SendEmail("(Shopify)Quay Service Started",
                    "(Shopify)Quay Service Successfuly Started");
            }
            catch (Exception ex)
            {
                ProcessException(ex, "Error starting (Shopify)Quay Service");
                EventLog.WriteEntry("Error starting (Shopify)Quay service and timer..." + ex.Message);
            }
        }
        protected override void OnStop()
        {
            try
            {
                if (scheduler != null)
                {
                    scheduler.Stop();
                }

                SendEmail("(Shopify)Quay Service stopped",
                    "(Shopify)Quay Service Successfuly Stopped");
            }
            catch (Exception ex)
            {
                ProcessException(ex, "Error stopping (Shopify)Quay Service");
                EventLog.WriteEntry("Error stopping (Shopify)Quay timer and service..." + ex.Message);
            }
        }
        private void SendEmail(string subject, string body)
        {
            new Email().SendErrorEmail("Quay", subject, body);
        }
        private void ProcessException(Exception ex,
            string customMessage)
        {
            var innerException = "";
            if (ex.InnerException != null)
                innerException = (!string.IsNullOrWhiteSpace(ex.InnerException.Message)) ? ex.InnerException.Message : "";


            new Email().SendErrorEmail("Quay", customMessage, 
                ex.Message + " " + innerException);
        }
    } 

非常容易设置并解决了我使用 Timers.Timer 的可怕经历虽然我没有解决核心问题,但我想出了一个解决方案并得到了一个没有错误的工作系统。

未来的读者请注意请勿使用 System.Timers.Timer,除非您准备添加 "hack'ish" 修复。