3

In a .NET 6 Web application I added a Quartz Job to run a daily task. The quartz job is added using .AddQuartz and .AddQuartzHostedService as shown on https://www.quartz-scheduler.net/documentation/quartz-3.x/packages/hosted-services-integration.html#installation page

What can I do to make the Quartz Scheduler/Jobs start when the application pool starts?

Quartz does start running correctly after the first web request is made to the application. In IIS I have set the AppPools Start Mode to AlwaysRunning,the .NET CLR Version to both No Managed Code or v4.0. I installed Application Initialization on the web server and set the applications Preload Enabled property to True.

When IIS starts up, a w3wp.exe task starts using the application pools AD identity. After the first web request, a new conhost.exe task starts on the web server also using the application pools AD identity which I assume is the Quartz scheduler running. I checked the Event Viewer for errors and I am not finding anything that appears to be related to this issue.

This is the Program.cs of the web app.

using Microsoft.AspNetCore.Authentication.Negotiate;
using Microsoft.EntityFrameworkCore;
using DataChecker_3186.Data;
using DataChecker_3186.Models;
using Quartz;
using DataChecker_3186.IdmsInterface;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddDbContext<FitProContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("FitProContext")));
builder.Services.AddDbContext<HITSContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("HITSContext")));

builder.Services.AddScoped<ILookupLists, LookupLists>();

builder.Services.AddControllersWithViews();

builder.Services.AddRazorPages();

builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
   .AddNegotiate();

builder.Services.AddAuthorization(options =>
{
    options.FallbackPolicy = options.DefaultPolicy;
});

builder.Services.AddTransient<IIdmsService, IdmsService>();

var sendJobKey = new JobKey("SendToIdms");
var watchJobKey = new JobKey("MonitorIdmsOutput");
var sendToIdmsCron = builder.Configuration.GetValue<string>("IdmsInterfaceSettings:SendToIdmsCron");
var monitorIdmsOutputCron = builder.Configuration.GetValue<string>("IdmsInterfaceSettings:MonitorIdmsOutputCron");

builder.Services.AddQuartz(q =>
{
    q.SchedulerId = "MaskFitRecordsJobScheduler";
    q.SchedulerName = "MaskFitRecords Job Scheduler";
    q.UseMicrosoftDependencyInjectionJobFactory();
    q.AddJob<SendToIdmsJob>(opts => opts.WithIdentity(sendJobKey));
    q.AddJob<ProcessIdmsOutput>(opts => opts.WithIdentity(watchJobKey));

    q.AddTrigger(opts => opts
        .WithIdentity(sendJobKey.Name + "-trigger")
        .ForJob(sendJobKey)
        .StartNow()
        .WithCronSchedule(sendToIdmsCron));

    q.AddTrigger(opts => opts
        .ForJob(watchJobKey)
        .WithIdentity(watchJobKey.Name + "-trigger")
        .WithCronSchedule(monitorIdmsOutputCron));
});

builder.Services.AddTransient<SendToIdmsJob>();
builder.Services.AddTransient<ProcessIdmsOutput>();

builder.Services.AddQuartzHostedService(q =>
    {
        q.WaitForJobsToComplete = true;
    });

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=FitTests}/{action=Index}/{id?}");

app.Run();
  • You can try to write the code to start the scheduler in Application_Start event of global.asax, and you can also refer to this link: [https://stackoverflow.com/questions/11140597/iis-app-pool-recycle-quartz-scheduling](https://stackoverflow.com/questions/11140597/iis-app-pool-recycle-quartz-scheduling). – samwu Apr 15 '22 at 02:45
  • Thanks for the link and in digging through it appears to be applicable of earlier versions of .Net Core. In .NET 6 there is no global.asax file and with the QuartzHostedService there is not a start function that I can find for the scheduler. I believe it starts with the app.Run() command. If I had to guess it is between Application Initialization feature and .NET 6. I need to figure out how monitor and see if Application Initialization is doing anything for this web application. – Richard Waggoner Apr 18 '22 at 17:07
  • It is difficult to reproduce your problem, I suggest you open a case via: https://support.microsoft.com. – samwu Apr 19 '22 at 06:28
  • @RichardWaggoner did you manage to find the solution? – Viktor Jan 10 '23 at 10:51

0 Answers0