Programing

매일 작업을 수행하도록 C # Windows 서비스를 예약하려면 어떻게해야합니까?

lottogame 2020. 9. 20. 10:32
반응형

매일 작업을 수행하도록 C # Windows 서비스를 예약하려면 어떻게해야합니까?


C # (. NET 1.1)으로 작성된 서비스가 있으며 매일 밤 자정에 정리 작업을 수행하기를 원합니다. 모든 코드를 서비스 내에 포함시켜야하는데이를 수행하는 가장 쉬운 방법은 무엇입니까? 사용 Thread.Sleep()및 롤오버 시간 확인?


Thread.Sleep ()을 사용하지 않을 것입니다. 다른 사람들이 언급했듯이 예약 된 작업을 사용하거나 서비스 내부에 타이머를 설정하여 주기적으로 (예 : 10 분마다) 실행하고 마지막 실행 이후 날짜가 변경되었는지 확인합니다.

private Timer _timer;
private DateTime _lastRun = DateTime.Now.AddDays(-1);

protected override void OnStart(string[] args)
{
    _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)
{
    // ignore the time, just compare the date
    if (_lastRun.Date < DateTime.Now.Date)
    {
        // stop the timer while we are running the cleanup task
        _timer.Stop();
        //
        // do cleanup stuff
        //
        _lastRun = DateTime.Now;
        _timer.Start();
    }
}

Quartz.NET을 확인하십시오 . Windows 서비스 내에서 사용할 수 있습니다. 구성된 일정에 따라 작업을 실행할 수 있으며 간단한 "cron 작업"구문도 지원합니다. 나는 그것으로 많은 성공을 거두었습니다.

다음은 사용법에 대한 간단한 예입니다.

// Instantiate the Quartz.NET scheduler
var schedulerFactory = new StdSchedulerFactory();
var scheduler = schedulerFactory.GetScheduler();

// Instantiate the JobDetail object passing in the type of your
// custom job class. Your class merely needs to implement a simple
// interface with a single method called "Execute".
var job = new JobDetail("job1", "group1", typeof(MyJobClass));

// Instantiate a trigger using the basic cron syntax.
// This tells it to run at 1AM every Monday - Friday.
var trigger = new CronTrigger(
    "trigger1", "group1", "job1", "group1", "0 0 1 ? * MON-FRI");

// Add the job to the scheduler
scheduler.AddJob(job, true);
scheduler.ScheduleJob(trigger);

일상적인 일? 예약 된 작업 (제어판)이어야하는 것처럼 들립니다. 여기에서 서비스가 필요하지 않습니다.


실제 서비스 여야합니까? Windows 제어판에서 내장 된 예약 된 작업을 사용할 수 있습니다.


이것을 달성하는 방법은 타이머를 사용하는 것입니다.

서버 타이머를 실행하고 60 초마다시 / 분을 확인하도록합니다.

올바른 시간 / 분이면 프로세스를 실행하십시오.

실제로 이것을 OnceADayRunner라고 부르는 기본 클래스로 추상화했습니다.

코드를 조금 정리하고 여기에 게시하겠습니다.

    private void OnceADayRunnerTimer_Elapsed(object sender, ElapsedEventArgs e)
    {
        using (NDC.Push(GetType().Name))
        {
            try
            {
                log.DebugFormat("Checking if it's time to process at: {0}", e.SignalTime);
                log.DebugFormat("IsTestMode: {0}", IsTestMode);

                if ((e.SignalTime.Minute == MinuteToCheck && e.SignalTime.Hour == HourToCheck) || IsTestMode)
                {
                    log.InfoFormat("Processing at: Hour = {0} - Minute = {1}", e.SignalTime.Hour, e.SignalTime.Minute);
                    OnceADayTimer.Enabled = false;
                    OnceADayMethod();
                    OnceADayTimer.Enabled = true;

                    IsTestMode = false;
                }
                else
                {
                    log.DebugFormat("Not correct time at: Hour = {0} - Minute = {1}", e.SignalTime.Hour, e.SignalTime.Minute);
                }
            }
            catch (Exception ex)
            {
                OnceADayTimer.Enabled = true;
                log.Error(ex.ToString());
            }

            OnceADayTimer.Start();
        }
    }

이 메서드의 핵심은 e.SignalTime.Minute / Hour 검사에 있습니다.

테스트 등을위한 후크가 있지만 이것이 모든 작업을 수행하기 위해 경과 된 타이머의 모습입니다.


다른 사람들이 이미 작성했듯이 타이머는 설명한 시나리오에서 가장 좋은 옵션입니다.

Depending on your exact requirements, checking the current time every minute may not be necessary. If you do not need to perform the action exactly at midnight, but just within one hour after midnight, you can go for Martin's approach of only checking if the date has changed.

If the reason you want to perform your action at midnight is that you expect a low workload on your computer, better take care: The same assumption is often made by others, and suddenly you have 100 cleanup actions kicking off between 0:00 and 0:01 a.m.

In that case you should consider starting your cleanup at a different time. I usually do those things not at clock hour, but at half hours (1.30 a.m. being my personal preference)


I would suggest that you use a timer, but set it to check every 45 seconds, not minute. Otherwise you can run into situations where with heavy load, the check for a particular minute is missed, because between the time the timer triggers and the time your code runs and checks the current time, you might have missed the target minute.


You can also try the TaskSchedulerLibrary here http://visualstudiogallery.msdn.microsoft.com/a4a4f042-ffd3-42f2-a689-290ec13011f8

Implement the abstract class AbstractScheduledTask and call the ScheduleUtilityFactory.AddScheduleTaskToBatch static method


For those that found the above solutions not working, it's because you may have a this inside your class, which implies an extension method which, as the error message says, only makes sense on a non-generic static class. Your class isn't static. This doesn't seem to be something that makes sense as an extension method, since it's acting on the instance in question, so remove the this.


Try this:

public partial class Service : ServiceBase
{
    private Timer timer;
    public Service()
    {
        InitializeComponent();
    }

    protected override void OnStart(string[] args)
    {
        SetTimer();
    }

    private void SetTimer()
    {
        if (timer == null)
        {
            timer = new Timer();
            timer.AutoReset = true;
            timer.Interval = 60000 * Convert.ToDouble(ConfigurationManager.AppSettings["IntervalMinutes"]);
            timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
            timer.Start();
        }
    }

    private void timer_Elapsed(object source, System.Timers.ElapsedEventArgs e)
    {
        //Do some thing logic here
    }

    protected override void OnStop()
    {
        // disposed all service objects
    }
}

참고URL : https://stackoverflow.com/questions/503564/how-might-i-schedule-a-c-sharp-windows-service-to-perform-a-task-daily

반응형