2

Windows サービスを実行しています。その中で、タスクは現在毎日午後 7 時に実行されます。たとえば、午前 9 時 45 分、午前 11 時 45 分、午後 2 時、午後 3 時 45 分、午後 5 時、午後 5 時 45 分に実行する最善の方法は何ですか。

関数を実行するタスクをスケジュールできることはわかっていますが、Windows サービス内でこれを行う方法を知りたいです。以下の現在のコード:

private Timer _timer;
private DateTime _lastRun = DateTime.Now;
private static readonly log4net.ILog log = log4net.LogManager.GetLogger
(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

protected override void OnStart(string[] args)
{
    // SmartImportService.WebService.WebServiceSoapClient test = new WebService.WebServiceSoapClient();
    // test.Import();
     log.Info("Info - Service Started");
    _timer = new Timer(10 * 60 * 1000); // every 10 minutes??
    _timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
    _timer.Start();
}

private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    log.Info("Info - Check time");
    DateTime startAt = DateTime.Today.AddHours(19);
    if (_lastRun < startAt && DateTime.Now >= startAt)
    {
        // stop the timer 
        _timer.Stop();               

        try
        {
           log.Info("Info - Import");
           SmartImportService.WebService.WebServiceSoapClient test = new WebService.WebServiceSoapClient();
           test.Import();
        }
        catch (Exception ex) {
           log.Error("This is my error - ", ex);
        }
        _lastRun = DateTime.Now;
        _timer.Start();
   }
}
4

4 に答える 4

5

cron や Quartz を使用したくない場合は、現在と次の実行の間の時間間隔を見つける関数を作成し、それに応じてタイマーをリセットし、サービスの開始と時間経過イベントでこの関数を呼び出します。あなたはこのようなことをするかもしれません(コードはテストされていません)

   System.Timers.Timer _timer;
    List<TimeSpan> timeToRun = new List<TimeSpan>();
    public void OnStart(string[] args)
    {

        string timeToRunStr = "20:45;20:46;20:47;20:48;20:49";
        var timeStrArray = timeToRunStr.Split(';');
        CultureInfo provider = CultureInfo.InvariantCulture;

        foreach (var strTime in timeStrArray)
        {
            timeToRun.Add(TimeSpan.ParseExact(strTime, "g", provider));
        }
        _timer = new System.Timers.Timer(60*100*1000);
        _timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
        ResetTimer();
    }


    void ResetTimer()
    {
        TimeSpan currentTime = DateTime.Now.TimeOfDay;
        TimeSpan? nextRunTime = null;
        foreach (TimeSpan runTime in timeToRun)
        {

            if (currentTime < runTime)
            {
                nextRunTime = runTime;
                break;
            }
        }
        if (!nextRunTime.HasValue)
        {
            nextRunTime = timeToRun[0].Add(new TimeSpan(24, 0, 0));
        }
        _timer.Interval = (nextRunTime.Value - currentTime).TotalMilliseconds;
        _timer.Enabled = true;

    }

    private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        _timer.Enabled = false;
        Console.WriteLine("Hello at " + DateTime.Now.ToString());
        ResetTimer();
    }
于 2012-04-30T08:40:42.227 に答える
5

Quartz.netCronTriggerの使用を検討してください。

于 2012-04-30T08:29:34.397 に答える
0

実行するスケジュールが明確な場合は、 timeelapsed イベントのタイマーの時間間隔を変更して、スケジュールに従って実行されるようにします..試したことはありませんが

于 2012-04-30T08:25:05.197 に答える
0

バックグラウンド スレッドを使用して、作業を行い、15 分間スリープする無限ループを実行させます。タイマーを使用するよりも、サービス コードがはるかにクリーンでシンプルになります。

MSDN のこの記事を参照してください。

于 2012-04-30T08:27:36.553 に答える