在 C# 中每天运行一次
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/280566/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Run once a day in C#
提问by Anders R
Is there any clever method out there to make my executeEveryDayMethod() execute once a day, without having to involve the Windows TaskScheduler?
有没有什么聪明的方法可以让我的 executeEveryDayMethod() 每天执行一次,而不必涉及 Windows TaskScheduler?
采纳答案by reshefm
Take a look at quartz.net. It is a scheduling library for .net.
看看quartz.net。它是.net 的调度库。
More specifically take a look here.
更具体的看这里。
回答by Vinko Vrsalovic
If the time when it is run is not relevant and can be reset each time the program starts you can just set a timer, which is the easiest thing to do. If that's not acceptable it starts getting more complex, like the solution presented hereand which still doesn't solve the persistence problem, you need to tackle that separately if you truly wish to do what Scheduled Tasks would. I'd really consider again if it's worth going through all the trouble to replicate a perfectly good existing functionality.
如果它运行的时间不相关并且可以在每次程序启动时重置,您只需设置一个计时器,这是最简单的事情。如果这是不可接受的,它开始变得更加复杂,就像这里提供的解决方案一样,但仍然不能解决持久性问题,如果您真的希望执行计划任务,则需要单独解决该问题。我真的会再次考虑是否值得为复制一个完美的现有功能而付出所有的麻烦。
Here's a related question(Example taken from there).
这是一个相关的问题(从那里获取的示例)。
using System;
using System.Timers;
public class Timer1
{
private static Timer aTimer = new System.Timers.Timer(24*60*60*1000);
public static void Main()
{
aTimer.Elapsed += new ElapsedEventHandler(ExecuteEveryDayMethod);
aTimer.Enabled = true;
Console.WriteLine("Press the Enter key to exit the program.");
Console.ReadLine();
}
// Specify what you want to happen when the Elapsed event is
// raised.
private static void ExecuteEveryDayMethod(object source, ElapsedEventArgs e)
{
Console.WriteLine("The Elapsed event was raised at {0}", e.SignalTime);
}
}
回答by Robert Gould
You could query time and run if your within some time frame, that way even if the machine goes off you'll call the method or use a timer like Vinko's suggestion.
您可以查询时间并在某个时间范围内运行,这样即使机器关闭,您也会调用该方法或使用像 Vinko 建议的计时器。
But the better solution (akin to older CRON versions, so its a proven pattern) is to have some persistent data, with the cheapest solution I can think of right now being a blank file, check its last modified attribute, and if it hasn't been modified within the last 24 hours you touch it and run your method. This way you assure the method gets run first thing in the case the application is out for the weekend for example.
但是更好的解决方案(类似于旧的 CRON 版本,因此它是一种经过验证的模式)是拥有一些持久数据,我现在能想到的最便宜的解决方案是一个空白文件,检查其最后修改的属性,如果没有t 在您触摸它并运行您的方法的最后 24 小时内被修改。通过这种方式,您可以确保在应用程序周末外出的情况下首先运行该方法。
I've done this in C# before, but its was a year ago at another Job, so I don't have the code but it was about 20 lines (with comments and all) or so.
我以前在 C# 中做过这个,但它是一年前在另一个工作中完成的,所以我没有代码,但它大约有 20 行(包括注释和全部)左右。
回答by ZombieSheep
I achieved this by doing the following...
我通过执行以下操作实现了这一点......
- Set up a timer that fires every 20 minutes (although the actual timing is up to you - I needed to run on several occasions throughout the day).
- on each Tick event, check the system time. Compare the time to the scheduled run time for your method.
- If the current time is less than the scheduled time, check a in some persistent storage to get the datetime value of the last time the method ran.
- If the method last ran more than 24 hours ago, run the method, and stash the datetime of this run back to your data store
- If the method last ran within the last 24 hours, ignore it.
- 设置一个每 20 分钟触发一次的计时器(尽管实际时间由您决定 - 我需要全天运行几次)。
- 在每个 Tick 事件上,检查系统时间。将时间与您的方法的计划运行时间进行比较。
- 如果当前时间小于预定时间,则在某个持久存储中检查 a 以获取该方法上次运行的日期时间值。
- 如果该方法上次运行超过 24 小时,请运行该方法,并将此次运行的日期时间存储回您的数据存储
- 如果该方法最后一次运行是在过去 24 小时内,请忽略它。
HTH
HTH
*edit - code sample in C# :: Note : untested...
* 编辑 - C# 中的代码示例 :: 注意:未经测试...
using System;
using System.Collections.Generic;
using System.Text;
using System.Timers;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
Timer t1 = new Timer();
t1.Interval = (1000 * 60 * 20); // 20 minutes...
t1.Elapsed += new ElapsedEventHandler(t1_Elapsed);
t1.AutoReset = true;
t1.Start();
Console.ReadLine();
}
static void t1_Elapsed(object sender, ElapsedEventArgs e)
{
DateTime scheduledRun = DateTime.Today.AddHours(3); // runs today at 3am.
System.IO.FileInfo lastTime = new System.IO.FileInfo(@"C:\lastRunTime.txt");
DateTime lastRan = lastTime.LastWriteTime;
if (DateTime.Now > scheduledRun)
{
TimeSpan sinceLastRun = DateTime.Now - lastRan;
if (sinceLastRun.Hours > 23)
{
doStuff();
// Don't forget to update the file modification date here!!!
}
}
}
static void doStuff()
{
Console.WriteLine("Running the method!");
}
}
}
回答by HenryHey
There may be problems if the computer reboots so you could run the application as a windows service.
如果计算机重新启动,则可能会出现问题,因此您可以将该应用程序作为 Windows 服务运行。
回答by drinky
To run the job once daily between 7 and 8pm, i set up a timer with interval = 3600000 ms and then just execute the following code for timer tick.
为了每天在晚上 7 点到 8 点之间运行一次作业,我设置了一个间隔 = 3600000 毫秒的计时器,然后只需执行以下代码进行计时器滴答。
private void timer1_Tick(object sender, EventArgs e)
{
//ensure that it is running between 7-8pm daily.
if (DateTime.Now.Hour == 19)
{
RunJob();
}
}
An hour window is fine for me. Extra granularity on time will require a smaller interval on the timer (60000 for a minute) and including minutes on the if.
一个小时的窗口对我来说很好。额外的时间粒度将需要更小的计时器间隔(一分钟 60000),包括 if 上的分钟。
eg
例如
{
//ensure that it is running at 7:30pm daily.
if (DateTime.Now.Hour == 19 && DateTime.Now.Minute == 30)
{
RunJob();
}
}
回答by HopeThisHelps
If you only want to run it once a day and don't care when, this will work (will run just after midnight).
如果您只想每天运行一次并且不关心何时运行,这将起作用(将在午夜之后运行)。
Declare a DateTime
variable:
声明一个DateTime
变量:
DateTime _DateLastRun;
In your startup, set the initial date value:
在您的启动中,设置初始日期值:
_DateLastRun = DateTime.Now.Date;
In the logic area where you want to check whether to perform the action:
在要检查是否执行动作的逻辑区:
if (_DateLastRun < DateTime.Now.Date)
{
// Perform your action
_DateLastRun= DateTime.Now.Date;
}