我正在尝试在.NET Core中开发一个简单的API,允许异步处理请求。
由于应用程序将在IIS上运行,因此在控制器返回响应后可能会发生池循环。我想实现一种方法,允许应用程序正常关闭 - 完成它当前正在执行的任务,但不接受任何新的。
我很难将优雅的关机运行结束。出于测试目的,我简化了StopAsync()
方法,所以现在它只包含一个异步的20秒等待:
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.");
}
}
日志只显示show:
看看EventViewer我可以看到为关闭引发的2个事件,它们之间恰好有10秒:
我已经尝试过了:
在Program.cs
上设置关闭超时
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseShutdownTimeout(TimeSpan.FromMinutes(1));
检查应用程序池的高级设置:
如果你做过类似的事情,如果我做错了/指出我正确的方向,你能告诉我吗?
谢谢!
编辑
在调试应用程序时,使用CTRL + C关闭会产生预期的行为。
我再次看一下这个问题后找到了解决方案。
看起来IIS中的ASP.NET核心模块有一个单独的关闭时间限制,可以在web.config
文件中配置为:
<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/en-us/aspnet/core/host-and-deploy/aspnet-core-module?view=aspnetcore-2.1
理想情况下,这应该可以通过代码获得,这仍然是我想要解决的问题。如果您找到了解决方法,请分享评论。