如何在以Windows服务运行的ASP.Net Core WebApp中执行长时间初始化?

时间:2019-05-07 10:19:31

标签: asp.net-core initialization windows-services

那里有许多资源讨论如何在ASP.Net Core WebApp中处理长时间运行的初始化(例如数据库迁移)(例如,请参见herehere)。当前的共识似乎是在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运行长时间初始化的正确方法是什么?在启动过程中,是否可以从操作系统中请求更多时间?

0 个答案:

没有答案