如何在C#中的特定时间每天调用方法?
我搜索了这么多,找到了关于Quartz.net的答案。但这对我的项目来说似乎太大了。我想要一个等效的解决方案,但更简单(最多)是代码(不需要外部库)。我如何每天在特定时间调用一个方法 我需要补充一些关于这方面的信息:如何在C#中的特定时间每天调用方法?,c#,winforms,methods,scheduled-tasks,C#,Winforms,Methods,Scheduled Tasks,我搜索了这么多,找到了关于Quartz.net的答案。但这对我的项目来说似乎太大了。我想要一个等效的解决方案,但更简单(最多)是代码(不需要外部库)。我如何每天在特定时间调用一个方法 我需要补充一些关于这方面的信息: 最简单(也是最难看)的方法是每秒钟/分钟检查一次时间,并在正确的时间调用该方法 我想要一个更有效的方法来做这件事,不需要经常检查时间,我可以控制工作是否完成。如果该方法失败(由于任何问题),程序应该知道如何写入日志/发送电子邮件。这就是为什么我需要调用一个方法,而不是计划一个作
- 最简单(也是最难看)的方法是每秒钟/分钟检查一次时间,并在正确的时间调用该方法
- 创建一个可以满足您需要的控制台应用程序
- 使用Windows“”功能在需要运行该控制台应用时执行该应用
- 在Windows窗体应用程序中,您可以点击事件并检查是否达到了一天中调用方法的时间。此方法仅在您的应用程序不忙于处理其他内容时调用。我认为,快速检查一下你的目标时间是否已经达到,不应该给你的应用程序带来太大的压力
- 在ASP.NET web应用程序中,有一些方法可以“模拟”发送计划事件-请查看此
- 当然,您也可以在任何.NET应用程序中简单地“滚动您自己的应用程序”——请查看此示例实现
using System.Timers;
const double interval60Minutes = 60 * 60 * 1000; // milliseconds to one hour
Timer checkForTime = new Timer(interval60Minutes);
checkForTime.Elapsed += new ElapsedEventHandler(checkForTime_Elapsed);
checkForTime.Enabled = true;
然后在事件处理程序中:
void checkForTime_Elapsed(object sender, ElapsedEventArgs e)
{
if (timeIsReady())
{
SendEmail();
}
}
我所知道的最好的方法,可能也是最简单的方法是使用Windows任务调度器在一天中的特定时间执行代码,或者让应用程序永久运行并检查一天中的特定时间,或者编写一个Windows服务来执行相同的操作 如果要运行可执行文件,请使用Windows计划任务。我将假设(可能是错误的)您希望在当前程序中运行一个方法 为什么不让一个线程连续运行来存储调用该方法的最后日期呢
让它每分钟唤醒一次(例如),如果当前时间大于指定时间且存储的最后日期不是当前日期,则调用该方法,然后更新日期。正如其他人所说,您可以使用控制台应用程序按计划运行。其他人没有说的是,这个应用程序可以触发一个跨进程的EventWaitHandle,您正在主应用程序中等待它 控制台应用程序:
class Program
{
static void Main(string[] args)
{
EventWaitHandle handle =
new EventWaitHandle(true, EventResetMode.ManualReset, "GoodMutexName");
handle.Set();
}
}
private void Form1_Load(object sender, EventArgs e)
{
// Background thread, will die with application
ThreadPool.QueueUserWorkItem((dumby) => EmailWait());
}
private void EmailWait()
{
EventWaitHandle handle =
new EventWaitHandle(false, EventResetMode.ManualReset, "GoodMutexName");
while (true)
{
handle.WaitOne();
SendEmail();
handle.Reset();
}
}
主应用程序:
class Program
{
static void Main(string[] args)
{
EventWaitHandle handle =
new EventWaitHandle(true, EventResetMode.ManualReset, "GoodMutexName");
handle.Set();
}
}
private void Form1_Load(object sender, EventArgs e)
{
// Background thread, will die with application
ThreadPool.QueueUserWorkItem((dumby) => EmailWait());
}
private void EmailWait()
{
EventWaitHandle handle =
new EventWaitHandle(false, EventResetMode.ManualReset, "GoodMutexName");
while (true)
{
handle.WaitOne();
SendEmail();
handle.Reset();
}
}
每当我构建需要此类功能的应用程序时,我总是通过我找到的一个简单的.NET库使用Windows任务调度程序
请获取一些示例代码和更多解释。我知道这是旧的,但是这个怎么样:
构建一个计时器,在启动时启动,计算到下一个运行时间的时间。在运行时的第一次调用中,取消第一个计时器并启动一个新的每日计时器。将“每日”更改为“每小时”或任何您希望的周期。您可以计算剩余时间,并将计时器设置为该周期的一半(或其他部分),而不是设置每60分钟每秒运行一次的时间。这样,你就不需要检查太多的时间,但也要保持一定的准确度,因为越接近目标时间,计时器间隔越短 例如,如果您想在60分钟后完成某项任务,则计时器的间隔将是近似的: 30:00:00,15:00:00,07:30:00,03:45:00,00:00:01,快跑 我使用下面的代码每天自动重新启动一次服务。我使用线程是因为我发现计时器在很长一段时间内都不可靠,而在这个例子中,它的成本更高,因为它是唯一一个为此目的创建的线程,所以这无关紧要 (从VB.NET转换而来)
private void autoRestartThreadRun()
{
试一试{
DateTime nextRestart=DateAndTime.Today.Add(CurrentSettings.AutoRestartTime);
if(nextRestart
注:我已将最小间隔设置为1000毫秒,可根据需要的精度增加、减少或删除
雷米
public void RestartApp()
{
AppRestart = AppRestart.AddHours(5);
AppRestart = AppRestart.AddMinutes(30);
DateTime current = DateTime.Now;
if (current > AppRestart) { AppRestart = AppRestart.AddDays(1); }
TimeSpan UntilRestart = AppRestart - current;
int MSUntilRestart = Convert.ToInt32(UntilRestart.TotalMilliseconds);
tmrRestart.Interval = MSUntilRestart;
tmrRestart.Elapsed += tmrRestart_Elapsed;
tmrRestart.Start();
}
while (true)
{
if(DateTime.Now.ToString("HH:mm") == "22:00")
{
//do something here
//ExecuteFunctionTask();
//Make sure it doesn't execute twice by pausing 61 seconds. So that the time is past 2200 to 2201
Thread.Sleep(61000);
}
Thread.Sleep(10000);
}
private void DoSomething(int aHour, int aMinute)
{
bool running = true;
while (running)
{
Thread.Sleep(1);
if (DateTime.Now.Hour == aHour && DateTime.Now.Minute == aMinute)
{
Thread.Sleep(60 * 1000); //Wait a minute to make the if-statement false
//Do Stuff
}
}
}
TaskScheduler.Instance.ScheduleTask(11, 52, 0.00417,
() =>
{
Debug.WriteLine("task1: " + DateTime.Now);
//here write the code that you want to schedule
});
TaskScheduler.Instance.ScheduleTask(11, 52, 0.00139,
() =>
{
Debug.WriteLine("task2: " + DateTime.Now);
//here write the code that you want to schedule
});
task2: 07.06.2017 11:52:00
task1: 07.06.2017 11:52:00
task2: 07.06.2017 11:52:05
task2: 07.06.2017 11:52:10
task1: 07.06.2017 11:52:15
task2: 07.06.2017 11:52:15
task2: 07.06.2017 11:52:20
task2: 07.06.2017 11:52:25
...
public class TaskScheduler
{
private static TaskScheduler _instance;
private List<Timer> timers = new List<Timer>();
private TaskScheduler() { }
public static TaskScheduler Instance => _instance ?? (_instance = new TaskScheduler());
public void ScheduleTask(int hour, int min, double intervalInHour, Action task)
{
DateTime now = DateTime.Now;
DateTime firstRun = new DateTime(now.Year, now.Month, now.Day, hour, min, 0, 0);
if (now > firstRun)
{
firstRun = firstRun.AddDays(1);
}
TimeSpan timeToGo = firstRun - now;
if (timeToGo <= TimeSpan.Zero)
{
timeToGo = TimeSpan.Zero;
}
var timer = new Timer(x =>
{
task.Invoke();
}, null, timeToGo, TimeSpan.FromHours(intervalInHour));
timers.Add(timer);
}
}
void ScheduleSomething()
{
var runAt = DateTime.Today + TimeSpan.FromHours(16);
if (runAt <= DateTime.Now)
{
DoSomething();
}
else
{
var delay = runAt - DateTime.Now;
System.Threading.Tasks.Task.Delay(delay).ContinueWith(_ => DoSomething());
}
}
void DoSomething()
{
// do somethig
}
var DailyTime = "16:59:00";
var timeParts = DailyTime.Split(new char[1] { ':' });
var dateNow = DateTime.Now;
var date = new DateTime(dateNow.Year, dateNow.Month, dateNow.Day,
int.Parse(timeParts[0]), int.Parse(timeParts[1]), int.Parse(timeParts[2]));
TimeSpan ts;
if (date > dateNow)
ts = date - dateNow;
else
{
date = date.AddDays(1);
ts = date - dateNow;
}
//waits certan time and run the code
Task.Delay(ts).ContinueWith((x) => OnTimer());
public void OnTimer()
{
ViewBag.ErrorMessage = "EROOROOROROOROR";
}
using System;
using System.Timers;
namespace ScheduleTimer
{
class Program
{
static Timer timer;
static void Main(string[] args)
{
schedule_Timer();
Console.ReadLine();
}
static void schedule_Timer()
{
Console.WriteLine("### Timer Started ###");
DateTime nowTime = DateTime.Now;
DateTime scheduledTime = new DateTime(nowTime.Year, nowTime.Month, nowTime.Day, 8, 42, 0, 0); //Specify your scheduled time HH,MM,SS [8am and 42 minutes]
if (nowTime > scheduledTime)
{
scheduledTime = scheduledTime.AddDays(1);
}
double tickTime = (double)(scheduledTime - DateTime.Now).TotalMilliseconds;
timer = new Timer(tickTime);
timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
timer.Start();
}
static void timer_Elapsed(object sender, ElapsedEventArgs e)
{
Console.WriteLine("### Timer Stopped ### \n");
timer.Stop();
Console.WriteLine("### Scheduled Task Started ### \n\n");
Console.WriteLine("Hello World!!! - Performing scheduled task\n");
Console.WriteLine("### Task Finished ### \n\n");
schedule_Timer();
}
}
}
private void nameOfMethod()
{
//do something
}
/// <summary>
/// run method at 22:00 every day
/// </summary>
private void runMethodEveryDay()
{
var runAt = DateTime.Today + TimeSpan.FromHours(22);
if(runAt.Hour>=22)
runAt = runAt.AddDays(1.00d); //if aplication is started after 22:00
var dueTime = runAt - DateTime.Now; //time before first run ;
long broj3 = (long)dueTime.TotalMilliseconds;
TimeSpan ts2 = new TimeSpan(24, 0, 1);//period of repeating method
long broj4 = (long)ts2.TotalMilliseconds;
timer2 = new System.Threading.Timer(_ => nameOfMethod(), null, broj3, broj4);
}
using System;
using System.Threading;
using System.Threading.Tasks;
namespace DailyWorker
{
class Program
{
static void Main(string[] args)
{
var cancellationSource = new CancellationTokenSource();
var utils = new Utils();
var task = Task.Run(
() => utils.DailyWorker(12, 30, 00, () => DoWork(cancellationSource.Token), cancellationSource.Token));
Console.WriteLine("Hit [return] to close!");
Console.ReadLine();
cancellationSource.Cancel();
task.Wait();
}
private static void DoWork(CancellationToken token)
{
while (!token.IsCancellationRequested)
{
Console.Write(DateTime.Now.ToString("G"));
Console.CursorLeft = 0;
Task.Delay(1000).Wait();
}
}
}
public class Utils
{
public void DailyWorker(int hour, int min, int sec, Action someWork, CancellationToken token)
{
while (!token.IsCancellationRequested)
{
var dateTimeNow = DateTime.Now;
var scanDateTime = new DateTime(
dateTimeNow.Year,
dateTimeNow.Month,
dateTimeNow.Day,
hour, // <-- Hour when the method should be started.
min, // <-- Minutes when the method should be started.
sec); // <-- Seconds when the method should be started.
TimeSpan ts;
if (scanDateTime > dateTimeNow)
{
ts = scanDateTime - dateTimeNow;
}
else
{
scanDateTime = scanDateTime.AddDays(1);
ts = scanDateTime - dateTimeNow;
}
try
{
Task.Delay(ts).Wait(token);
}
catch (OperationCanceledException)
{
break;
}
// Method to start
someWork();
}
}
}
}
using System;
using System.Timers;
namespace ConsoleApp
{
internal class Scheduler
{
private static readonly DateTime scheduledTime =
new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 10, 0, 0);
private static DateTime dateTimeLastRunTask;
internal static void CheckScheduledTask()
{
if (dateTimeLastRunTask.Date < DateTime.Today && scheduledTime.TimeOfDay < DateTime.Now.TimeOfDay)
{
Console.WriteLine("Time to run task");
dateTimeLastRunTask = DateTime.Now;
}
else
{
Console.WriteLine("not yet time");
}
}
}
internal class Program
{
private static Timer timer;
static void Main(string[] args)
{
timer = new Timer(5000);
timer.Elapsed += OnTimer;
timer.Start();
Console.ReadLine();
}
private static void OnTimer(object source, ElapsedEventArgs e)
{
Scheduler.CheckScheduledTask();
}
}
}
DateTime startTime = DateTime.Today.AddDays(1).AddHours(8).AddMinutes(30); // Today starts at midnight, so add the number of days, hours and minutes until the desired start time, which in this case is the next day at 8:30 a.m.
TimeSpan waitFor = startTime - DateTime.Now; // Calcuate how long it is until the start time
await Task.Delay(waitFor); // Wait until the start time