Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/306.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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中设置在特定时间执行的计时器#_C#_Multithreading_Timer - Fatal编程技术网

C# 如何在c中设置在特定时间执行的计时器#

C# 如何在c中设置在特定时间执行的计时器#,c#,multithreading,timer,C#,Multithreading,Timer,我有一个要求,我需要在每天早上00:01:00执行计时器…但我不知道如何实现这一点…如果我占用系统时间,它可以是不同的格式。。 这是我的计时器代码 static System.Timers.Timer timer; timer = new System.Timers.Timer(); timer.Interval = 1000 * 60 * 60 * 24;//set interval of one day timer.Elapsed += new ElapsedEventHandler(tim

我有一个要求,我需要在每天早上00:01:00执行计时器…但我不知道如何实现这一点…如果我占用系统时间,它可以是不同的格式。。 这是我的计时器代码

static System.Timers.Timer timer;
timer = new System.Timers.Timer();
timer.Interval = 1000 * 60 * 60 * 24;//set interval of one day
timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
start_timer(); 

static void timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        // Add timer code here

    }
    private static void start_timer()
    {
        timer.Start();
    }

您可以随时计算它:

static void timer_Elapsed(object sender, ElapsedEventArgs e)
{
    // Do stuff

    start_timer();
}

private static void start_timer()
{
    timer.Interval = CalculateInterval();
    timer.Start();
}

private static double CalculateInterval()
{
    // 1 AM the next day
    return (DateTime.Now.AddDays(1).Date.AddHours(1) - DateTime.Now).TotalMilliseconds;
}

你应该做的是编写你的程序,让它做任何你需要它做的事情,然后使用你的操作系统内置的任务调度器来启动它。那是最可靠的。例如,Windows的任务调度程序可以在用户登录之前启动应用程序,在必要时处理重新启动应用程序,记录错误和发送通知等

否则,你将不得不全天候运行你的应用程序,并让它定期轮询时间

例如,您可以每分钟更改一次间隔:

timer.Interval = 1000 * 60;
已用时间
事件中,检查当前时间:

static void timer_Elapsed(object sender, ElapsedEventArgs e)
{
    if (DateTime.Now.Hour == 1 && DateTime.Now.Minute == 0)
    {
        // do whatever
    }
}

但这确实不可靠。你的应用程序可能会崩溃。处理日期时间可能会很棘手。

如果你想在凌晨00:01:00am启动计时器,请做一些处理时间,然后重新启动计时器,你只需要计算现在的
和下一个凌晨00:01:00am时间段之间的差,例如

static Timer timer;
static void Main(string[] args)
{
    setup_Timer();
}

static void setup_Timer()
{
    DateTime nowTime = DateTime.Now;
    DateTime oneAmTime = new DateTime(nowTime.Year, nowTime.Month, nowTime.Day, 0, 1, 0, 0);
    if (nowTime > oneAmTime)
        oneAmTime = oneAmTime.AddDays(1);

    double tickTime = (oneAmTime - nowTime).TotalMilliseconds;
    timer = new Timer(tickTime);
    timer.Elapsed += timer_Elapsed;
    timer.Start();
}

static void timer_Elapsed(object sender, ElapsedEventArgs e)
{
    timer.Stop();
    //process code..
    setup_Timer();
}

这是一个计时器实现,它采用一个间隔(就像任何其他计时器一样),并在该间隔到期时准确触发,即使机器在其间进入睡眠模式

public delegate void TimerCallbackDelegate(object sender, ElapsedEventArgs e);
public class TimerAbsolute : System.Timers.Timer
{
    private DateTime m_dueTime;
    private TimerCallbackDelegate callback;

    public TimerAbsolute(TimerCallbackDelegate cb) : base()
    {
        if (cb == null)
        {
            throw new Exception("Call back is NULL");
        }
        callback = cb;
        this.Elapsed += this.ElapsedAction;
        this.AutoReset = true;
    }

    protected new void Dispose()
    {
        this.Elapsed -= this.ElapsedAction;
        base.Dispose();
    }

    public double TimeLeft
    {
        get
        {
            return (this.m_dueTime - DateTime.Now).TotalMilliseconds;
        }
    }

    public int TimeLeftSeconds
    {
        get
        {
            return (int)(this.m_dueTime - DateTime.Now).TotalSeconds;
        }
    }


    public void Start(double interval)
    {
        if (interval < 10)
        {
            throw new Exception($"Interval ({interval}) is too small");
        }

        DateTime dueTime = DateTime.Now.AddMilliseconds(interval);

        if (dueTime <= DateTime.Now)
        {
            throw new Exception($"Due time ({dueTime}) should be in future. Interval ({interval})");
        }
        this.m_dueTime = dueTime;

        // Timer tick is 1 second
        this.Interval = 1 * 1000;
        base.Start();
    }

    private void ElapsedAction(object sender, System.Timers.ElapsedEventArgs e)
    {
        if (DateTime.Now >= m_dueTime)
        {
            // This means Timer expired
            callback(sender, e);
            base.Stop();
        }
    }
}
public委托void TimerCallbackDelegate(对象发送方,ElapsedEventArgs e);
公共类TimerAbsolute:System.Timers.Timer
{
私人约会时间;
私有TimerCallbackDelegate回调;
公共TimerAbsolute(TimerCallbackDelegate cb):base()
{
如果(cb==null)
{
抛出新异常(“回调为空”);
}
回调=cb;
this.appead+=this.ElapsedAction;
this.AutoReset=true;
}
受保护的新void Dispose()
{
this.appead-=this.ElapsedAction;
base.Dispose();
}
公共双时限
{
得到
{
return(this.m_dueTime-DateTime.Now).total毫秒;
}
}
公共整数时间倒数秒
{
得到
{
return(int)(this.m_dueTime-DateTime.Now).TotalSeconds;
}
}
公共无效开始(双间隔)
{
如果(间隔<10)
{
抛出新异常($“Interval({Interval})太小”);
}
DateTime dueTime=DateTime.Now.AddMillimes(间隔);
如果(dueTime=m_dueTime)
{
//这意味着计时器已过期
回调(发送方,e);
base.Stop();
}
}
}

这行不通。计时器不准确,因为它测量的是滴答声,它们可以被高cpu使用率抵消。一个更好的链接描述了为什么这是有问题的@Mick它不需要是一个实时问题。大概在凌晨1点或者凌晨1点1秒,他想发生什么事。计时器确实会有轻微的延迟。但对于大多数情况来说,这已经足够好了。对于一千个场景,您可以使用MMTimer,但这不起作用。计时器不准确stackoverflow.com/questions/10605639/…它测量的是滴答声,它们可能会被高cpu的usageNico的答案所抵消,因此不准确或不可靠。格兰特的答案是一个更好的解决方案,你需要投票并对照DateTime进行检查