代码之家  ›  专栏  ›  技术社区  ›  Alexei - check Codidact

如何在IIS中优雅地结束带有ASP.NET Core 2.2作业的Quartz 3.0.x?

  •  1
  • Alexei - check Codidact  · 技术社区  · 5 年前

    我正试图优雅地结束在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?

    1 回复  |  直到 5 年前
        1
  •  1
  •   Rabban    5 年前

    你可以给 true 到“scheduler.shutdown()”等待作业完成。这将延迟池关闭,直到作业运行结束。

    lifetime.ApplicationStopping.Register(() => scheduler.Shutdown(true));
    

    你可以多读一些 here .

    推荐文章