Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Windows服务-它能否以不同的时间间隔运行两个单独的任务_C#_.net_Service_Windows Services - Fatal编程技术网

C# 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(

我已经写了一个Windows服务,它在一周的特定时间触发一次电子邮件。服务运行得非常好。代码如下所示:

  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();
    }
}