正常关闭IHostedService [英] Graceful shutdown of IHostedService

查看:411
本文介绍了正常关闭IHostedService的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在.NET Core中开发一个简单的API,该API允许异步处理请求.

I am trying to develop a simple API in .NET Core that allows asynchronous processing of requests.

  1. 请求已发送至控制器
  2. 在后台服务(IHostedService)上安排的工作
  3. 控制器返回202
  4. 后台服务执行长时间运行的操作

由于该应用程序将在IIS上运行,因此控制器返回响应后,可能会发生池回收.我想实现一种允许应用程序正常关闭的方法-完成它当前正在执行的任务,但不接受任何新任务.

As the application will be running on IIS, a pool recycle can happen after the controller has returned a response. I would like to implement a way to allow the application to do a graceful shutdown - finishing it's currently executing tasks, but not accepting any new.

我无法正常关闭关机. 为了进行测试,我简化了StopAsync()方法,因此现在它只包含一个异步20秒等待时间:

I am having difficulties having the graceful shutdown run to end. For testing purposes I've simplified the StopAsync() method, so now it only contains an async 20 second wait:

public async Task StopAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("Hosted service is stopping...");

        try
        {
            // Signal cancellation to the executing method
            _stoppingTokenSource.Cancel();

            _logger.LogInformation("Delay by 20s");
            await Task.Delay(20000, cancellationToken);
            _logger.LogInformation("Delay over");
        }
        finally
        {
            // Await all pending download requests
            await Task.WhenAny(Task.WhenAll(_pendingTasks), Task.Delay(Timeout.Infinite, cancellationToken));

            _logger.LogInformation("Hosted service has been stopped successfully.");
        }
    }

仅显示日志:

  • 托管服务正在停止...
  • 延迟20秒

查看 EventViewer ,我可以看到在关闭之间恰好有10秒的时间触发了2个事件:

Looking at EventViewer I can see 2 events raised for the shutdown with exactly 10 seconds in between them:

  • 已发送关闭HTTP消息以处理'11104',并收到http状态'202'.
  • 无法正常关闭进程'11104'.

我已经尝试过:

设置Program.cs

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>()
            .UseShutdownTimeout(TimeSpan.FromMinutes(1));

检查应用程序池的高级设置:

Check Advanced Settings of application pool:

如果您做过类似的事情,请告诉我我做错了什么/指出正确的方向吗?

If you have done something similar, could you please let me know if I'm doing something wrong / point me in the right direction?

谢谢!

编辑

在调试应用程序时,使用CTRL + C关闭会产生预期的行为.

While debugging the application, shutting down with CTRL + C produces the expected behaviour.

推荐答案

再次查看该问题后,我找到了解决方案.

I've found a solution after having another look at the issue again.

似乎IIS中的ASP.NET Core模块有一个单独的关闭时间限制,可以在web.config文件中将其配置为:

It seems like ASP.NET Core Module in IIS have a separate shutdown time limit, which can be configured in the web.config file as:

    <configuration>
      <system.webServer>
        <handlers>
          <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
        </handlers>
        <aspNetCore
            shutdownTimeLimit="30"    - set timeout here in seconds
            processPath="dotnet"
            arguments=".\GracefulShutdown.dll"
            stdoutLogEnabled="false"
            stdoutLogFile=".\logs\stdout" />
      </system.webServer>
    </configuration>

有关以下位置的设置: https://docs.microsoft.com/zh-CN/aspnet/core/host-and-deploy/aspnet-core-module?view=aspnetcore-2.1

Reference to settings at: https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/aspnet-core-module?view=aspnetcore-2.1

理想情况下,这应该可以通过代码获得,这仍然是我要解决的问题.如果您找到解决方法,请发表评论.

Ideally this should be available through code, which is still something I'm trying to resolve. If you find a way to do it, please share in comment.

这篇关于正常关闭IHostedService的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆