Я пытаюсь изящно завершить задание Quartz, которое выполняется в IIS. Мой код выглядит следующим образом:
работа
[DisallowConcurrentExecution]
public class TestJob : IJob
{
private ILoggingService Logger { get; }
private IApplicationLifetime ApplicationLifetime { get; }
private static object lockHandle = new object();
private static bool shouldExit = false;
public TestJob(ILoggingService loggingService, IApplicationLifetime applicationLifetime)
{
Logger = loggingService;
ApplicationLifetime = applicationLifetime;
}
public Task Execute(IJobExecutionContext context)
{
//TODO: does not seem work
//context.CancellationToken.Register(() =>
//{
// lock (lockHandle)
// {
// shouldExit = true;
// }
//});
return Task.Run(() =>
{
//TODO: check
ApplicationLifetime.ApplicationStopping.Register(() =>
{
lock (lockHandle)
{
shouldExit = true;
}
});
try
{
for (int i = 0; i < 10; i ++)
{
lock (lockHandle)
{
if (shouldExit)
{
Logger.LogDebug($"TestJob detected that application is shutting down - exiting");
break;
}
}
Logger.LogDebug($"TestJob ran step {i+1}");
Thread.Sleep(3000);
}
}
catch (Exception exc)
{
Logger.LogError(exc, "An error occurred during execution of scheduled job");
}
});
}
}
Startup.cs
protected void StartJobs(IApplicationBuilder app, IApplicationLifetime lifetime)
{
var scheduler = app.ApplicationServices.GetService<IScheduler>();
//TODO: use some config
QuartzServicesUtilities.StartJob<TestJob>(scheduler, TimeSpan.FromSeconds(60));
lifetime.ApplicationStarted.Register(() => scheduler.Start());
lifetime.ApplicationStopping.Register(() => scheduler.Shutdown());
}
private static void ConfigureApplicationLifetime(ILoggingService logger, IApplicationLifetime lifetime)
{
lifetime.ApplicationStopping.Register(() =>
{
logger.LogInfo(null, "Application is stopping...");
});
lifetime.ApplicationStopped.Register(() =>
{
logger.LogInfo(null, "Application stopped");
});
}
Итак, я подключился к ApplicationStopping
, чтобы иметь возможность корректно завершать работу Quartz. Однако, когда пул приложений IIS заканчивается, задания завершаются внезапно:
- изменить что-то в web.config, чтобы вызвать остановку пула приложений
- Пул приложений настроен так, чтобы разрешать до 90 секунд до окончания. Также допускается перекрытие
- регистрация записей
Application is stopping
и немедленно Application stopped
, таким образом, работа завершается внезапно
Я помню, что аналогичная реализация работала в ASP.NET с Quartz 2.x: заданиям Quartz было разрешено завершить свою работу при условии, что им удалось сделать это в период завершения работы пула приложений.
Вопрос: Как изящно завершить работу Quartz 3.0.x с ASP.NET Core 2.2 в IIS?