Search code examples
c#scheduled-tasksdynamics-365

ScheduledJob using IScheduler in .NET not firing exactly at midnight


I have a Scheduled job that needs to be run everyday at mignight exactly. So I have created a trigger using IScheduler to be triggered at mignight. But it is getting triggered each day at different timings. Sometimes at 1am. Some time at 10.45am and so on.

The Task is created using IScheduler

// get a scheduler
IScheduler scheduler = await factory.GetScheduler();
await scheduler.Start();

The Job is

// define the job and tie it to our DailyVisitsJob class
IJobDetail job = JobBuilder.Create<DailyVisitsJob>()
                .WithIdentity("myJob", "group1")
                .Build();

The trigger is created like

ITrigger dailyTrigger = TriggerBuilder.Create()
                .WithIdentity("dailyTrigger", "group1")
                .WithSchedule(CronScheduleBuilder.DailyAtHourAndMinute(0, 0)) // Midnight (00:00)
                .Build();

The Job is for creating a few rows in Dynamics 365 table each day at midnight for the following day's bookings. But the job is not getting triggered everyday at the same time.


Solution

  • Thanks Jason Pan for your comment and reference. My working code to run the job every day at midnight is:

    ITrigger dailyTrigger = TriggerBuilder.Create()
    .WithDailyTimeIntervalSchedule(
        s => s.WithIntervalInHours(24)
            .StartingDailyAt(TimeOfDay.HourAndMinuteOfDay(0, 0))
            .InTimeZone(TimeZoneInfo.Utc))
    .Build();
    

    However, I found the below two settings in IIS was required to run the job successfully at midnight every day. The reason being, this scheduler was part of a web application that I am deploying to IIS. And the problem is that the deployed site is idle for most of the times and gets recycled or shutdown automatically by the application pool hence shutting down the scheduler worker processes as well. To avoid this, change the two settings as below:

    1. Open IIS Manager
    2. Expand the server node and expand 'Application Pools'
    3. Right click on your application pool and choose 'Advanced Settings'
    4. Change the 'Start Mode' from 'On demand' to 'AlwaysRunning'
    5. Change the Idle Timeout to 0 (disabling idle timeout)

    Screenshot for IIS Application Pool Advanced settings

    Note: Changing these settings will make the web application always available and running even if there are no requests. So this might be utilizing server resources even when idle.