如何在 IIS 上回收池后自动调用函数

How to automatically call a function after pool recycling on IIS

我想知道在 IIS 服务器使用 IIS -> 应用程序池 -> 回收上的 Web 数据回收设置后,我用 C#.NET5 (+React) 调用函数编写的 Web 应用程序的诀窍(固定时间间隔(以分钟为单位))设置于 1440.

我向内存(IMemoryCache)加载了超过 6 GB 并且需要超过 6 分钟然后加载所有数据,我想在回收期的每个循环之后调用加载函数自动缓存,然后等待用户互动。

我尝试在 StartUp 和 Main 中调用它,也尝试使用 IHostetServices,但在每种情况下,我都遇到错误,然后无法识别调用服务(我的 class 使用加载方法)

3 Ways to Run Code Once at Application Startup in ASP.NET Core


我遇到了这些错误:当我尝试调用

{"Unable to resolve service for type Repository.DataFilters.Static.IGroupLoader' while attempting to activate 'Search.Startup'."}

当我尝试调用时:

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");               
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseSpaStaticFiles();

        // Add other security headers
        app.UseMiddleware<SecurityHeadersMiddleware>();

        
        app.UseSerilogRequestLogging();

        app.UseRouting();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller}/{action=Index}/{id?}");
        });

        app.UseSpa(spa =>
        {
            spa.Options.SourcePath = "ClientApp";

            var isDev = env.EnvironmentName.Contains("Dev");

            if (env.IsDevelopment() || isDev)
            {
                spa.UseReactDevelopmentServer(npmScript: "start");
            }
        });

        _GroupLoader.LoadGroupFiltersToMemory(); // try to call this method from my class

    }

在配置服务中:

    private readonly IGroupLoader _GroupLoader;

    public Startup(IConfiguration configuration, IGroupLoader groupLoader)
    {
        Configuration = configuration;
        _GroupLoader = groupLoader;
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllersWithViews();
        services.AddMemoryCache();

        // DB Contexts
        services.AddDbContext<GroupContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

        // Services
        services.AddScoped<IGroupService, GroupService>();

        // Repositories
        services.AddScoped<IGroupLoader, GroupLoader>();

        services.AddSpaStaticFiles(configuration =>
        {
            configuration.RootPath = "ClientApp/build";
        });
    }

此解决方案不起作用:

<system.webServer>
            <aspNetCore xdt:Transform="SetAttributes(startupTimeLimit)" startupTimeLimit="300">
            </aspNetCore>
        </system.webServer>

IIS 运行s 回收后,貌似没有加载应用程序,我必须像打开网站link一样初始化运行,是否可以加载应用程序在 IIS 回收过程后自动执行?

在 Startup.cs 中我无法调用 await 函数 调用的函数用了 8 分钟,然后加载了所有数据

看来我必须使用:https://docs.microsoft.com/en-us/iis/get-started/whats-new-in-iis-8/iis-80-application-initialization#TOC301259895


更新 09.01.2022

在我将 IIS 和 App 设置为自动启动后,出现了这个错误:

我尝试这样做: https://serverfault.com/questions/590865/how-can-i-warm-up-my-asp-net-mvc-webapp-after-an-app-pool-recycle

在web.config我设置:

<applicationInitialization
    remapManagedRequestsTo="Startup.html" 
    skipManagedModules="true" >
  <add initializationPage="/subpage" />
</applicationInitialization>
  1. 然后当我尝试调用页面 /subpage(不使用 Startup.cs -> 配置调用 IMemoryCache 函数),加载到的函数 IMemoryCache 没有被调用,但是当我 运行 应用 Visual Studio 或者 在没有自动启动(预热)的情况下将应用程序部署到 IIS,一个函数是 打电话。

  2. 当我尝试通过以下方式调用函数(加载 IMemoryCache)时 Startup.cs -> Configure 函数,该函数被调用但是 IIS 服务器启动了很多(10-11 个进程)IIS Worker Process 并且我得到 上层错误,也Startup.html网页在调用过程中没有被调用 加载过程(我不确定 .NET 5 中必须位于何处 带有 React 解决方案的核心 Web 应用程序)。

我收到这个错误:

System.InvalidOperationException: Execution Timeout Expired.  The timeout period elapsed prior to completion of the operation or the server is not responding.

这可能是由于许多调用相同函数的 IIS Worker 进程造成的(在我使用的 IMemoryCache 加载函数中 lock()

谢谢

在设置依赖项注入之前,您无法将 IGroupLoader 依赖项注入到 Startup.cs 中 - 这由您提供的错误描述。

根据这个 guide,一旦你在 ConfigureServices.

中设置了依赖注入,你就可以在 Configure 中注入依赖

即你需要改变:

来自

 private readonly IGroupLoader _GroupLoader;

 public Startup(IConfiguration configuration, IGroupLoader groupLoader)
 {
     Configuration = configuration;
     _GroupLoader = groupLoader;
 }

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

来自

 public void Configure(IApplicationBuilder app, IWebHostEnvironment env)

 public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IGroupLoader groupLoader)

来自

_GroupLoader.LoadGroupFiltersToMemory();

groupLoader.LoadGroupFiltersToMemory();