我正试图优雅地结束在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");
}
});
}
}
创业公司
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
能够优雅地关闭石英作业。但是,当即将结束IIS应用程序池时,作业将突然结束:
-
在web.config中更改某些内容以触发应用程序池停止
-
应用程序池配置为在结束前最多允许90秒。也允许重叠
-
测井记录
Application is stopping
立即
Application stopped
从而使工作突然完成
我记得在ASP.NET中使用Quartz 2.x:Quartz的一个类似的实现也可以完成它们的工作,前提是它们在应用程序池关闭期间成功完成了这项工作。
问题:
如何在IIS中优雅地结束带有ASP.NET Core 2.2作业的Quartz 3.0.x?