如何编写C#调度程序

11

我该如何编写一个警报,让它每天在 00:00、00:15、00:30 等时间运行?

你能给我一个示例代码吗?

谢谢。


你是在谈论编写一个每15分钟运行一次的Windows服务吗? - K Mehta
2
通常情况下,如果您真的需要这样做,可以使用Quartz.NET。如果您不需要它具有“抗性”,则可以使用.NET计时器轻松完成。 - xanatos
1
一个标准的定时任务,运行一个可执行文件,通常是一个很好的选择,因为它简单易创建,并且您可以给管理员提供广泛的配置选项(身份、细粒度计划等)。 - Steve B
6个回答

12
你可以使用每分钟运行的计时器来检查当前时间。检查的代码可以是这样的:
private void OnTimerTick()
{
    if(DateTime.Now.Minutes%15==0)
    {
        //Do something
    }
}

但如果您正在寻找一个需要每15分钟运行的程序或服务,您可以编写您的应用程序,然后使用Windows计划任务启动它。


11
你可以编写程序来在每次打开时执行某个特定任务,然后使用Windows计划任务在每天指定的时间执行你的程序。
这样,你的程序将更简单,而且你只需要关注需要实现的逻辑。调度将由Windows免费为您完成(假设您已经支付了Windows :))。
如果你真的想自己实现调度,那么有一些框架和库可以使用,比如这个:Quartz.NET

1
这也是我通常推荐的。使用任务计划程序,那就是它存在的目的。 - Harry Steinhilber
1
我发现Quartz.NET是一个可行的选择,但它1)将其IJob接口紧密耦合到quartz.dll上,并且2)要求每个数据都可序列化。这里是一个简单版本:https://github.com/mjeson/SimpleJobScheduler - Jeson Martajaya

3
这是一个基本的C#调度程序:
using System;
using System.Threading;
using System.Windows.Forms;
using System.IO;

public class TimerExample
{
    public static void Main()
    {
        bool jobIsEnabledA = true;
        bool jobIsEnabledB = true;
        bool jobIsEnabledC = true;

        Console.WriteLine("Starting at: {0}", DateTime.Now.ToString("h:mm:ss"));

        try
        {
            using (StreamWriter writer = File.AppendText("C:\\scheduler_log.txt"))
            {
                while (true)
                {
                    var currentTime = DateTime.Now.ToString("h:mm");

                    if (currentTime == "3:15" && jobIsEnabledA)
                    {
                        jobIsEnabledA = false;
                        ThreadPool.QueueUserWorkItem((state) => { MessageBox.Show(string.Format("Time to brush your teeth! {0}", currentTime) ); });
                    }

                    if (currentTime == "3:20" && jobIsEnabledB)
                    {
                        jobIsEnabledB = false;
                        ThreadPool.QueueUserWorkItem((state) => { MessageBox.Show(string.Format("Time to brush your teeth! {0}", currentTime)); });
                    }

                    if (currentTime == "3:30" && jobIsEnabledC)
                    {      
                        jobIsEnabledC = false;
                        ThreadPool.QueueUserWorkItem((state) => { MessageBox.Show(string.Format("Time for your favorite show! {0}", currentTime)); });
                    }

                    if (currentTime == "3:31")
                    {      
                        jobIsEnabledA = true;
                        jobIsEnabledB = true;
                        jobIsEnabledC = true;
                    }

                    var logText = string.Format("{0} jobIsEnabledA: {1} jobIsEnabledB: {2} jobIsEnabledC: {3}", DateTime.Now.ToString("h:mm:ss"), jobIsEnabledA, jobIsEnabledB, jobIsEnabledC);
                    writer.WriteLine(logText);

                    Thread.Sleep(1000);
                }
            }
        }
        catch (Exception exception)
        {
            Console.WriteLine(exception);
        }
    }
}

我想知道如果机器在处理其他线程时忙碌,是否会跳过作业的时间。我知道这不太可能,但是在Thread.Sleep(1000)之后,线程不会立即恢复的机会有多大? - qfactor77

1

例如:

using System.Timers;
    class Program
    {
        static void Main(string[] args)
        {
            Timer timer = new Timer();
            timer.Interval = new TimeSpan(0, 15, 0).TotalMilliseconds;
            timer.AutoReset = true;
            timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
            timer.Enabled = true;
        }

        static void timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            throw new NotImplementedException();
        }
    }

1

在.NET中有不同的计时器

  • System.Threading.Timer
  • System.Windows.Forms.Timer
  • System.Timers.Timer
根据您想要做什么(以及在哪个环境、线程安全等方面),您应该选择其中之一。
更多信息

1
如果您想创建一个定时执行某些代码的Windows服务,您需要创建服务项目(详见此处),并在该服务中使用Timer类(详见此处)。 如果您想在Windows应用程序执行时运行这些任务,请使用Windows.Forms.Timer,如前所述。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接