那里有许多资源讨论如何在ASP.Net Core WebApp中处理长时间运行的初始化(例如数据库迁移)(例如,请参见here或here)。当前的共识似乎是在IWebHost构建之后但实际运行之前在Program.cs中执行此类初始化。
在控制台或IIS中运行WebApp时,此方法工作正常。但是,当作为Windows服务运行时,我遇到了操作系统的30秒超时。
这是一些说明问题的代码。完整(但仍然很小)的示例可以在here中找到。
public class Program
{
public static void Main(string[] args)
{
var host = CreateWebHostBuilder(args).Build();
if (args.Contains("--initialize"))
LongRunningInitialization(host);
if (args.Contains("--console"))
host.Run();
else
host.RunAsService();
}
private static void LongRunningInitialization(IWebHost host)
{
var logger = host.Services.GetRequiredService<ILogger<Program>>();
logger.LogInformation("Doing long-running initialization (sleep for 35 seconds)");
Task.Delay(35000).Wait();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
}
public class Startup
{
public void Configure(IApplicationBuilder app)
=> app.Run(async (context) => await context.Response.WriteAsync("Hello World!"));
}
public class MyWebHostService : WebHostService
{
private readonly ILogger<MyWebHostService> Logger;
public MyWebHostService(IWebHost host)
: base(host)
{
AutoLog = true;
CanHandlePowerEvent = false;
CanHandleSessionChangeEvent = false;
CanPauseAndContinue = false;
CanShutdown = false;
CanStop = true;
ServiceName = "MyTestService";
Logger = host.Services.GetRequiredService<ILogger<MyWebHostService>>();
}
protected override void OnStarting(string[] args)
{
Logger.LogInformation("MyWebHostService.OnStarting");
// This doesn't help...
RequestAdditionalTime(60000);
base.OnStarting(args);
}
protected override void OnStarted()
{
Logger.LogInformation("MyWebHostService.OnStarted");
base.OnStarted();
}
}
public static class MyWebHostServiceExtensions
{
public static void RunAsService(this IWebHost host)
{
var myWebHostService = new MyWebHostService(host);
ServiceBase.Run(myWebHostService);
}
}
如果我这样注册并运行此服务:
sc.exe create MyTestService DisplayName= "My Test Service" binpath= "....\WindowsServiceStartupTest.dll --initialize"
sc.exe start MyTestService
我收到以下错误消息:
服务未及时响应启动或控制请求。
无需长时间运行的初始化,服务就可以正常启动。
请注意,在OnStarting
覆盖中,我尝试延长超时时间,但这无效。似乎OnStarting
在长时间的初始化之后被调用(为时已晚)。
所以我的问题是:为Windows Server WebApp运行长时间初始化的正确方法是什么?在启动过程中,是否可以从操作系统中请求更多时间?