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 中的请求限制...所以目前,我不知所措。
挠头和极度烦恼之后
不仅吞下了异常,定时器也没有引发事件!我的服务挂了,这特别难,因为它还吞下了异常。
现在我确实走上了 Threading.Timer
的一半实施路线
不要使用System.Windows.Forms.Timer因为它不起作用(这才有意义)。
不要使用System.Threading.Timer,因为它不起作用,请改用System.Timers.Timer。
不要使用System.Timers.Timer,因为它不起作用,请改用System.Threading.Timer。
Related question.
我真的不会为这些步骤带来的问题而烦恼,因为我的目标是专注于业务逻辑。所以我决定使用 Quartz.Net.
它让我的生活变得轻松多了,而且似乎工作得很好! 45-60 分钟的工作。
基本设置:
1,Nuget > 石英
2,新建文件夹 > QuartzComponents > 作业和计划
3、在各自的文件夹中添加了OrderJob.cs
和OrderJobSchedule.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" 修复。
我看过很多关于这个问题的帖子,但似乎没有一个符合我的标准。
话虽如此,这是我构建的第一个 "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 中的请求限制...所以目前,我不知所措。
不仅吞下了异常,定时器也没有引发事件!我的服务挂了,这特别难,因为它还吞下了异常。
现在我确实走上了 Threading.Timer
不要使用System.Windows.Forms.Timer因为它不起作用(这才有意义)。
不要使用System.Threading.Timer,因为它不起作用,请改用System.Timers.Timer。
不要使用System.Timers.Timer,因为它不起作用,请改用System.Threading.Timer。
Related question.
我真的不会为这些步骤带来的问题而烦恼,因为我的目标是专注于业务逻辑。所以我决定使用 Quartz.Net.
它让我的生活变得轻松多了,而且似乎工作得很好! 45-60 分钟的工作。
基本设置:
1,Nuget > 石英
2,新建文件夹 > QuartzComponents > 作业和计划
3、在各自的文件夹中添加了OrderJob.cs
和OrderJobSchedule.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" 修复。