C# 如何在ASP.NET Core 5.0 kestrel服务器关闭之前运行代码?用于在3.1中工作
在.NETCore3.1中,我有下面的代码,一切正常。然而,在.NET5.0中,我认为停止顺序已经改变,因此只有OnStarted函数被正确调用,而不是OnStopping和OnStopped。有没有办法解决这个问题?在我的项目中没有其他代码发生更改,我只是将代码改回3.1,将一些“init;”恢复为“set;”,一切正常C# 如何在ASP.NET Core 5.0 kestrel服务器关闭之前运行代码?用于在3.1中工作,c#,asp.net-core,C#,Asp.net Core,在.NETCore3.1中,我有下面的代码,一切正常。然而,在.NET5.0中,我认为停止顺序已经改变,因此只有OnStarted函数被正确调用,而不是OnStopping和OnStopped。有没有办法解决这个问题?在我的项目中没有其他代码发生更改,我只是将代码改回3.1,将一些“init;”恢复为“set;”,一切正常 public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaul
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostBuilderContext, services) =>
{
services.AddHostedService<LifetimeEventsHostedService>();
公共静态IHostBuilder CreateHostBuilder(字符串[]args)=>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostBuilderContext,服务)=>
{
services.AddHostedService();
使用系统线程;
使用System.Threading.Tasks;
使用Microsoft.Extensions.Hosting;
使用NLog;
命名空间xlwteam1.Services
{
///
///所有这些只是为了将SystemIsShuttingDown布尔值设置为true,以防止新的websocket连接
///并触发内存中所有数据的保存、刷新等。
/// https://stackoverflow.com/questions/60228641/asp-net-core-3-graceful-shutdown-throws-operationcanceledexception
///
公共类LifetimeEventsHostedService:IHostedService
{
私有只读IHostApplicationLifetime\u hostApplicationLifetime;
///
///记录器
///
私有静态只读记录器Log=LogManager.GetCurrentClassLogger();
公共生活时间事件存储服务(IHostApplicationLifetime主机应用程序LifeTime)
{
_hostApplicationLifetime=hostApplicationLifetime;
}
公共任务StartSync(CancellationToken CancellationToken)
{
Log.Info(“开始时注册…”);
_hostApplicationLifetime.ApplicationStarted.Register(OnStarted);
_hostApplicationLifetime.ApplicationStopping.Register(OnStopping);
_hostApplicationLifetime.ApplicationsStopped.Register(OnStopped);
返回Task.CompletedTask;
}
公共任务StopAsync(CancellationToken CancellationToken)
{
返回Task.CompletedTask;
}
私有空间
{
Log.Info(“OnStopped”);
}
私有void OnStopping()
{
Log.Info(“OnPrepareForStopping”);
//为了使系统不接受新连接的时间尽可能短
//让我们在阻止新连接之前做一些工作。
Program.PrepareForStopping(Log.Wait();
日志信息(“OnStopping”);
Startup.SystemIsShuttingDown=true;
Program.ToDoBeforeShutdown(Log.Wait();
Log.Info(“已完成安装”);
}
私有void OnStarted()
{
日志信息(“启动”);
}
}
}
为什么不在StopAsync
上执行所有操作?您正在同步调用异步方法,而不是使用您已经需要实现的异步方法您的代码是否依赖于此示例???@CamiloTerevinto我想在停止服务请求之前尽可能多地执行关闭工作,因此OnStopping是最重要的rtant部分。这意味着重新启动我的服务的停机时间不到10秒,即不可察觉。@Jehof是的,这是我的代码,因此我认为这是net5.0中的一个错误。您确定服务正常启动(调用了StartAsync)?设计中可能会有一些变化,使应用程序生命周期回调无法工作。您的最后一步是将代码放入StopAsync
,尽管并不总是确保调用它,但它几乎可以一直工作。
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using NLog;
namespace xlwteam1.Services
{
/// <summary>
/// All this just to set the SystemIsShuttingDown boolean to true to prevent new websocket connections
/// and trigger a save, flush etc of all data in memory.
/// https://stackoverflow.com/questions/60228641/asp-net-core-3-graceful-shutdown-throws-operationcanceledexception
/// </summary>
public class LifetimeEventsHostedService : IHostedService
{
private readonly IHostApplicationLifetime _hostApplicationLifetime;
/// <summary>
/// The logger
/// </summary>
private static readonly Logger Log = LogManager.GetCurrentClassLogger();
public LifetimeEventsHostedService(IHostApplicationLifetime hostApplicationLifetime)
{
_hostApplicationLifetime = hostApplicationLifetime;
}
public Task StartAsync(CancellationToken cancellationToken)
{
Log.Info("Registering OnStarting...");
_hostApplicationLifetime.ApplicationStarted.Register(OnStarted);
_hostApplicationLifetime.ApplicationStopping.Register(OnStopping);
_hostApplicationLifetime.ApplicationStopped.Register(OnStopped);
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
private void OnStopped()
{
Log.Info("OnStopped");
}
private void OnStopping()
{
Log.Info("OnPrepareForStopping");
// in order to make the time the system doesn't accept new connections as short as possible
// let us do some work even before we block new connections.
Program.PrepareForStopping(Log).Wait();
Log.Info("OnStopping");
Startup.SystemIsShuttingDown = true;
Program.ToDoBeforeShutdown(Log).Wait();
Log.Info("OnStopping finished");
}
private void OnStarted()
{
Log.Info("OnStarted");
}
}
}