web-dev-qa-db-ja.com

c#で特定の時間に実行するようにタイマーを設定する方法

私は毎日00:01:00 AMにタイマーを実行する必要があるという要件があります...しかし、これを達成する方法を取得していません。システム時間を使用している場合、異なる形式にすることができます。私のタイマーコード。

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();
    }
12
Adi

あなたがすべきことは、あなたがそれをするために必要なことを何でもするあなたのプログラムを書いて、それからあなたのOSのビルトインタスクスケジューラを使ってそれを実行させることです。それが最も信頼できるでしょう。たとえば、Windowsのタスクスケジューラは、ユーザーがログインする前にアプリを起動したり、必要に応じてアプリの再起動を処理したり、エラーをログに記録したり、通知を送信したりできます。

それ以外の場合は、アプリを24時間年中無休で実行し、定期的に時間をポーリングする必要があります。

たとえば、間隔を1分ごとに変更できます。

timer.Interval = 1000 * 60;

Elapsedイベント内で、現在の時刻を確認します。

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

しかし、これは本当に信頼できません。アプリがクラッシュする可能性があります。また、DateTimeの扱いには注意が必要です。

10
vivat pisces

ちょうど00:01:00 amにタイマーを開始したい場合は、処理時間を行ってからタイマーを再起動し、Nowと次の00:01:00 amタイムスロットなどとの差を計算する必要があります。

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();
}
27
Nico

以下は、(他のタイマーと同じように)間隔を取り、その間隔が経過したときにマシンがスリープモードに移行した場合でも正確に起動するタイマー実装です。

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();
        }
    }
}
1
Miraj Mohamed

あなたはいつでもそれを計算することができます:

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;
}
0
itsme86