asp.net核心应用程序中的IHostedService的实现,如何在没有IIS的第一个请求的情况下运行它?

问题描述 投票:2回答:1

我已经在asp.net核心网站中实现了IHostedService。它运作良好,但问题是我希望在托管服务器启动或IIS服务重新启动时启动它,但除非有第一个对网站的请求进入,否则它不会启动。

  • 该网站托管在IIS 10.0.18版上
  • AppPool处于“始终运行”模式
  • “ PreloadEnabled”在网站上为“ True”。
  • 将“ .NET CLR版本”设置为“无托管代码”或“ v4.0.xxxxxx”没有帮助。
  • dotnet核心版本为2.2,并且已安装dotnet核心托管捆绑包。

UPDATE 1:@Arthur建议的“应用程序初始化模块”没有帮助。既不在站点级别,也不在服务器级别。

我使用的配置:

    <applicationInitialization
         doAppInitAfterRestart="true"
         skipManagedModules="false"
         remapManagedRequestsTo="init.htm">
        <add initializationPage="/init.htm" hostName="localhost"/>
    </applicationInitialization>

UPDATE 2:这是我实现接口的方式

internal class PaymentQueueService : IHostedService, IDisposable
{
    private readonly ILogger _logService;
    private Timer _timerEnqueue;

    public PaymentQueueService(ILogger logService)
    {
        _logService = logService;
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
        _logService.LogInformation("Starting processing payments.");

        _timerEnqueue = new Timer(EnqueuePayments, null, TimeSpan.Zero,
            TimeSpan.FromSeconds(10));

        return Task.CompletedTask;
    }

    private void EnqueuePayments(object state)
    {
        _logService.LogInformation("Enqueueing Payments.");
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        _logService.LogInformation("Stopping processing payments.");

        _timerEnqueue?.Change(Timeout.Infinite, 0);

        return Task.CompletedTask;
    }

    public void Dispose()
    {
        _timerEnqueue?.Dispose();
    }
}

main.cs文件中的Program类:

public class Program
    {
        public static void Main(string[] args)
        {
            CreateWebHostBuilder(args).Build().Run();
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args).ConfigureServices(services =>
            {
                services.AddHostedService<PaymentQueueService>();
            }).Configure((IApplicationBuilder app) =>
            {

                app.UseMvc();
            })
                .UseStartup<Startup>();
    }

启动类:

public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {

        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostEnvironment env)
        {

        }
    }
c# asp.net-core iis .net-core iis-10
1个回答
0
投票

由于建议的“应用程序初始化模块”不起作用,因此您可以考虑与客户端进行通话

当第一个请求到达时,模块启动ASP.NET Core应用程序的进程,如果关闭或崩溃,则重新启动应用程序。

public class Program {
    static Lazy<HttpClient> client = new Lazy<HttpClient>();
    public static async Task Main(string[] args) {
        var host = CreateWebHostBuilder(args).Start();//non blocking start
        using (host) {
            bool started = false;
            do {
                var response = await client.Value.GetAsync("site root");
                started = response.IsSuccessStatusCode;
                await Task.Delay(someDelayHere);
            } while (!started);

            host.WaitForShutdown();
        }
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .ConfigureServices(services => {
                services.AddHostedService<PaymentQueueService>();
            })
            .Configure((IApplicationBuilder app) => {
                app.UseMvc();
            })
            .UseStartup<Startup>();
}

NOTE:

为了防止托管进程外的应用程序超时,请使用以下两种方法之一:

  • 通过外部服务对应用程序执行Ping操作,以使其保持运行状态。
  • 如果该应用仅托管后台服务,请避免IIS托管,而使用Windows Service托管ASP.NET Core应用。
© www.soinside.com 2019 - 2024. All rights reserved.