0

私はC#でこれを一般的に行う方法を調査しましたが、タスクのスケジュールを考え続けましたが、それが必要かどうかはわかりません。これが私が思いついたものです

 void MainPage_Loaded(Object sender, RoutedEventArgs e)
    {
        tomorrowAt8AM = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.AddDays(1).Day, 8, 0, 0);//This is always 'tomorrow' at 8 am.. I think.
        TimeSpan timeSpan = tomorrowAt8AM.Subtract(DateTime.Now);
        timer.Interval = timeSpan; 
        timer.Tick += new EventHandler(timerTick);

        queryDB();
        timer.Start();
    }

private void timerTick(object sender, EventArgs e)
    {
        queryDB();

        //Recalculate the time interval.
        tomorrowAt8AM = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.AddDays(1).Day, 8, 0, 0);//This is always 'tomorrow' at 8 am.. I think.
        TimeSpan newTimerInterval = tomorrowAt8AM.Subtract(DateTime.Now);
        timer.Interval = newTimerInterval; 
    }

アイデアは、「今」から「明日の午前 8 時」までの時間を調べ、そのタイムスパンを新しいタイマー間隔として設定することです。私の頭の中でこれはうまくいきます..これを行うためのより良い方法はありますか? 間隔を変更したため、タイマーを再起動する必要がありますか?

@Richard Deemingこれは、1月31日の場合に何が起こるかをテストするためのコードのスライスです。

 System.DateTime tomorrowAt8AM = new System.DateTime(DateTime.Now.Year, 2, 1, 8, 0, 0);//This is always the 'next' day at 8 am. 

        while (true)
        {
            DateTime temp = new DateTime(DateTime.Now.Year, 1, 31, DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second); 
            DateTime now = DateTime.Now;
            System.TimeSpan diff1 = tomorrowAt8AM.Subtract(temp);
            //Console.WriteLine(diff1.Days);
            Console.WriteLine("Days: {3}, Hours: {0}, Minutes: {1}, Seconds: {2}", diff1.Hours, diff1.Minutes, diff1.Seconds, diff1.Days);
            Thread.Sleep(1000); 
        }

このコードを実行すると、正しく動作するように見えます.月末に問題が発生する可能性はありますか?

4

1 に答える 1

2

「明日の午前 8 時」のコードが間違っています。1 月 31 日に何が起こるか考えてみましょう。

// DateTime.Now == 2013/01/31
// DateTime.Now.AddDays(1) == 2013/02/01
tomorrowAt8AM = new DateTime(2013, 1, 1, ...

また、夏時間で何が起こるかを考慮する必要があります。時計が進むと、コードは午前 9 時に実行されます。戻ると、午前 7 時に実行されます。これを避けるには、DateTimeOffset タイプを使用する必要があります。

DateTimeOffset tomorrowAt8AM = Date.Today.AddDays(1).AddHours(8);
TimeSpan interval = tomorrowAt8AM.Subtract(DateTimeOffset.Now);

DispatcherTimerは、 Interval プロパティを変更するとタイマーを自動的に更新します。タイマーを再起動する必要はありません。

MSDN のコメントを見ると、タイマーが正確に午前 8 時に起動することは保証されていません。

タイマーは、時間間隔が発生したときに正確に実行されることは保証されていませんが、時間間隔が発生する前に実行されないことは保証されています。

コードをテストして、タイマーが要件に対して十分に正確かどうかを確認する必要があります。

于 2013-01-16T19:35:56.020 に答える