如何在 IIS 中优雅地结束 Quartz 3.0.x with ASP.NET Core 2.2 作业?
How to gracefully end a Quartz 3.0.x with ASP.NET Core 2.2 job in IIS?
我正在尝试在 IIS 中优雅地结束 运行 的 Quartz 作业。我的代码如下:
这份工作
[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 作业完成其工作,前提是它们在应用程序池关闭期间设法完成。
问题:如何在 IIS 中使用 ASP.NET Core 2.2 作业优雅地结束 Quartz 3.0.x?
您可以给 true
一个 'scheduler.Shutdown()' 以等待作业完成。这应该会延迟池关闭,直到作业 运行 结束。
lifetime.ApplicationStopping.Register(() => scheduler.Shutdown(true));
您可以阅读更多相关信息 here。
我正在尝试在 IIS 中优雅地结束 运行 的 Quartz 作业。我的代码如下:
这份工作
[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 作业完成其工作,前提是它们在应用程序池关闭期间设法完成。
问题:如何在 IIS 中使用 ASP.NET Core 2.2 作业优雅地结束 Quartz 3.0.x?
您可以给 true
一个 'scheduler.Shutdown()' 以等待作业完成。这应该会延迟池关闭,直到作业 运行 结束。
lifetime.ApplicationStopping.Register(() => scheduler.Shutdown(true));
您可以阅读更多相关信息 here。