Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/316.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#中的特定时间每天调用方法?_C#_Winforms_Methods_Scheduled Tasks - Fatal编程技术网

如何在C#中的特定时间每天调用方法?

如何在C#中的特定时间每天调用方法?,c#,winforms,methods,scheduled-tasks,C#,Winforms,Methods,Scheduled Tasks,我搜索了这么多,找到了关于Quartz.net的答案。但这对我的项目来说似乎太大了。我想要一个等效的解决方案,但更简单(最多)是代码(不需要外部库)。我如何每天在特定时间调用一个方法 我需要补充一些关于这方面的信息: 最简单(也是最难看)的方法是每秒钟/分钟检查一次时间,并在正确的时间调用该方法 我想要一个更有效的方法来做这件事,不需要经常检查时间,我可以控制工作是否完成。如果该方法失败(由于任何问题),程序应该知道如何写入日志/发送电子邮件。这就是为什么我需要调用一个方法,而不是计划一个作

我搜索了这么多,找到了关于Quartz.net的答案。但这对我的项目来说似乎太大了。我想要一个等效的解决方案,但更简单(最多)是代码(不需要外部库)。我如何每天在特定时间调用一个方法

我需要补充一些关于这方面的信息:

  • 最简单(也是最难看)的方法是每秒钟/分钟检查一次时间,并在正确的时间调用该方法
我想要一个更有效的方法来做这件事,不需要经常检查时间,我可以控制工作是否完成。如果该方法失败(由于任何问题),程序应该知道如何写入日志/发送电子邮件。这就是为什么我需要调用一个方法,而不是计划一个作业

我在Java中找到了这个解决方案。C#中有类似的方式吗

编辑:我已经做到了。我在void Main()中添加了一个参数,并创建了一个bat(由Windows任务调度器调度)来运行带有此参数的程序。程序运行、执行作业,然后退出。如果作业失败,它可以编写日志并发送电子邮件。这种方法非常适合我的要求:)

  • 创建一个可以满足您需要的控制台应用程序
  • 使用Windows“”功能在需要运行该控制台应用时执行该应用
这才是你真正需要的

更新:如果您想在应用程序中执行此操作,您有几个选项:

  • Windows窗体应用程序中,您可以点击事件并检查是否达到了一天中调用方法的时间。此方法仅在您的应用程序不忙于处理其他内容时调用。我认为,快速检查一下你的目标时间是否已经达到,不应该给你的应用程序带来太大的压力
  • 在ASP.NET web应用程序中,有一些方法可以“模拟”发送计划事件-请查看此
  • 当然,您也可以在任何.NET应用程序中简单地“滚动您自己的应用程序”——请查看此示例实现
更新#2:如果要每60分钟检查一次,可以创建一个计时器,每60分钟唤醒一次,如果时间到了,它会调用该方法

大概是这样的:

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