C# Windows服务-它能否以不同的时间间隔运行两个单独的任务
我已经写了一个Windows服务,它在一周的特定时间触发一次电子邮件。服务运行得非常好。代码如下所示:C# Windows服务-它能否以不同的时间间隔运行两个单独的任务,c#,.net,service,windows-services,C#,.net,Service,Windows Services,我已经写了一个Windows服务,它在一周的特定时间触发一次电子邮件。服务运行得非常好。代码如下所示: protected override void OnStart(string[] args) { this.Log("Simple Service Started"); this.ScheduleService(); } protected override void OnStop() { this.Log(
protected override void OnStart(string[] args)
{
this.Log("Simple Service Started");
this.ScheduleService();
}
protected override void OnStop()
{
this.Log("Simple Service Stopped");
this.Schedular.Dispose();
}
private Timer Schedular;
public void ScheduleService()
{
try
{
Schedular = new Timer(new TimerCallback(SchedularCallback));
// Code that schedules the Callback
}
}
private void SchedularCallback(object e)
{
try
{
// Scheduled Job code
}
}
现在我有另一个类似的要求,我必须触发另一封电子邮件,但它的时间表必须是每两周一次。有没有一种方法可以在同一个服务中适应此工作,或者我必须编写另一个服务?您可以很容易地在
ScheduleService
中启动第二个调度
,设置为在两周内启动,但是一个计时器
每一两周启动一次是一种可怕的方式,如果计算机重新启动,你会松开计时器,等待的电子邮件将不会发送
您需要某种数据库来存储下一个事件何时触发,以便在程序重新启动后继续生存,使用一个为您存储并执行日程安排的库。您可以轻松创建第二个
日程安排
,它在ScheduleService
中启动,设置为在两周内关闭,但是一个计时器
每一两周触发一次是一种可怕的方式,如果计算机重新启动,你会松开计时器,等待的电子邮件将不会发送
当下一个事件触发时,您需要存储某种类型的数据库,以便在程序重新启动后继续运行,使用一个库来存储并执行调度。是的,您可以使用多线程来实现这一点,例如通过或。有了它,您可以在不同的线程上启动每个计时器,当计时器滴答作响时,该线程将执行您的操作。建议在不同的线程上分离计时器和执行-例如,用于计时器1和2的Backgroundworkers和用于执行1和2的Backgroundworkers。是的,您可以使用多线程来实现这一点,例如通过或。有了它,您可以在不同的线程上启动每个计时器,当计时器滴答作响时,该线程将执行您的操作。建议在不同的线程上分离计时器和执行-例如,计时器1和2的Backgroundworkers和执行1和2的Backgroundworkers。我曾经在我的一个项目中做过类似的设计。 尝试创建一个定义计时行为的基本抽象“ScheduledTask”类,并让继承的任务类使用它 这是我为计时器所做的,我认为将其更改为调度程序所做的工作很少
internal abstract class TaskBase
{
/// <summary>
/// Task timer
/// </summary>
private readonly Timer _timer;
/// <summary>
/// Set refresh time
/// </summary>
protected int TimeRefreshSec { get; private set; }
/// <summary>
/// Loop of timePassed
/// </summary>
protected int TimePassed { get; private set; }
protected TaskBase(double refreshInterval)
{
TimeRefreshSec = (int) refreshInterval / 1000;
TimePassed = 0;
_timer = new Timer(refreshInterval) { AutoReset = true };
_timer.Elapsed += Tick;
}
private void Tick(object sender, ElapsedEventArgs e)
{
TimePassed += TimeRefreshSec;
Tick();
}
public void Start()
{
ResetTimer();
// Run the task once when starting instead of waiting for a full interval.
Tick();
OnStart();
}
public void Stop()
{
if (_timer.Enabled)
{
_timer.Stop();
OnStop();
}
}
protected virtual void ResetTimer()
{
TimePassed = 0;
if (_timer.Enabled) _timer.Stop();
_timer.Start();
}
/// <summary>
/// Implement here a specific behavior when task is stopped.
/// </summary>
protected abstract void OnStop();
/// <summary>
/// Implement here a specific behavior when task is started.
/// </summary>
protected abstract void OnStart();
/// <summary>
/// This method is executed each time the task's timer has reached the interval specified in the constructor.
/// Time counters are automatically updated.
/// </summary>
protected abstract void Tick();
}
我曾经在我的一个项目中做过类似的设计。 尝试创建一个定义计时行为的基本抽象“ScheduledTask”类,并让继承的任务类使用它 这是我为计时器所做的,我认为将其更改为调度程序所做的工作很少
internal abstract class TaskBase
{
/// <summary>
/// Task timer
/// </summary>
private readonly Timer _timer;
/// <summary>
/// Set refresh time
/// </summary>
protected int TimeRefreshSec { get; private set; }
/// <summary>
/// Loop of timePassed
/// </summary>
protected int TimePassed { get; private set; }
protected TaskBase(double refreshInterval)
{
TimeRefreshSec = (int) refreshInterval / 1000;
TimePassed = 0;
_timer = new Timer(refreshInterval) { AutoReset = true };
_timer.Elapsed += Tick;
}
private void Tick(object sender, ElapsedEventArgs e)
{
TimePassed += TimeRefreshSec;
Tick();
}
public void Start()
{
ResetTimer();
// Run the task once when starting instead of waiting for a full interval.
Tick();
OnStart();
}
public void Stop()
{
if (_timer.Enabled)
{
_timer.Stop();
OnStop();
}
}
protected virtual void ResetTimer()
{
TimePassed = 0;
if (_timer.Enabled) _timer.Stop();
_timer.Start();
}
/// <summary>
/// Implement here a specific behavior when task is stopped.
/// </summary>
protected abstract void OnStop();
/// <summary>
/// Implement here a specific behavior when task is started.
/// </summary>
protected abstract void OnStart();
/// <summary>
/// This method is executed each time the task's timer has reached the interval specified in the constructor.
/// Time counters are automatically updated.
/// </summary>
protected abstract void Tick();
}
如果服务只是在等待一天/一周中的正确时间等来做事情,但没有实现任何有用的东西,我建议使用windows计划任务(或任何其他计划软件),而不是将其作为自定义服务实现。如果服务只是在一天/一周中的正确时间等待,我建议使用windows计划任务(或任何其他计划软件),而不是将其作为自定义服务来实现。我认为这不是一种可怕的方式,因为他说必须在特定的时间完成。如果指定了时间(如
DateTime
)并将其保存在某个位置,则只需计算时间间隔,并在每次服务启动时进行设置。因此,如果电脑崩溃并重新启动,计时器将重新设置。我认为这样做并不可怕,因为他说必须在特定时间完成。如果指定了时间(如DateTime
)并将其保存在某个位置,则只需计算时间间隔,并在每次服务启动时进行设置。因此,如果电脑崩溃并重新启动,计时器将再次设置。请您提供一些示例代码,以使用任务和后台工作程序编写两个计划。请您提供一些示例代码,以使用任务和后台工作程序编写两个计划。这看起来很有希望:您可以共享继承类的实现,或者,其他继承类。这将是非常有帮助的,我在回答中添加了它,但是VS可能会告诉您如何实现它。那么,我如何分别为这两个类指定间隔(比如1周和2周)…它会在构造函数定义中吗?比如..public InheritingTask():base(604800000){//TODO:Custom initialization here}注意:604800000正好相当于一周的毫秒!因此,您的任务具有相同的定时行为,但间隔不同。是否有一种方法可以指定我是否需要在特定时间发送每周邮件:例如每周一,6pm这看起来很有希望:您可以共享继承类或其他继承类的实现吗。这将是非常有帮助的,我在回答中添加了它,但是VS可能会告诉您如何实现它。那么,我如何分别为这两个类指定间隔(比如1周和2周)…它会在构造函数定义中吗?比如..public InheritingTask():base(604800000){//TODO:Custom initialization here}注意:604800000正好相当于一周的毫秒!因此,您的任务具有相同的定时行为,但间隔不同。是否有一种方法可以指定我是否需要在特定时间发送每周邮件:例如每周一下午6点
class InheritingTask: TaskBase
{
public InheritingTask()
: base(Settings.Default.InheritingTaskInterval) // In milliseconds
{
//TODO: Custom initialization here
}
protected override void Tick()
{
//TODO: Task logic here
}
protected override void OnStart()
{ }
protected override void OnStop()
{ }
protected override void ResetTimer()
{
//TODO: Custom reset logic here
base.ResetTimer();
}
}