c# - 如何在没有 http 请求的情况下在 MVC 核心应用程序中启动 HostedService

标签 c# asp.net-core asp.net-core-hosted-services

在我的 MVC .NET core 2.2 应用程序中有 HostedService 做后台工作。

在Startap类的ConfigureServices方法中注册

services.AddHostedService<Engines.KontolerTimer>();

因为这是独立于用户请求的后台服务,所以我想在应用程序启动时立即启动我的后台服务。 现在是我的 HostedService 在第一次用户请求后启动的情况。

当 MVC 核心应用程序启动时启动 HostedService 的正确方法是什么

我的服务看起来像这个 https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-2.2

internal class TimedHostedService : IHostedService, IDisposable
{
    private readonly ILogger _logger;
    private Timer _timer;

    public TimedHostedService(ILogger<TimedHostedService> logger)
    {
        _logger = logger;
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("Timed Background Service is starting.");

        _timer = new Timer(DoWork, null, TimeSpan.Zero, 
            TimeSpan.FromSeconds(5));

        return Task.CompletedTask;
    }

    private void DoWork(object state)
    {
        _logger.LogInformation("Timed Background Service is working.");
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("Timed Background Service is stopping.");

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

        return Task.CompletedTask;
    }

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

看起来我在盯着应用程序时遇到了问题。

我的程序cs看起来像

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


        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
            .UseSerilog((ctx, config) => { config.ReadFrom.Configuration(ctx.Configuration); })
            .UseStartup<Startup>();
    }

而且在第一个用户请求之前我没有遇到任何断点。 我错过了什么吗,这是 VS2017 创建的默认 .Net Core 应用

这是我的 starup.cs

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

        public IConfiguration Configuration { get; }
        private Models.Configuration.SerialPortConfiguration serialPortConfiguration;

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(
                    Configuration.GetConnectionString("DefaultConnection")));

            services.AddIdentity<ApplicationUser, ApplicationRole>(options => options.Stores.MaxLengthForKeys = 128)
                .AddDefaultUI(UIFramework.Bootstrap4)
                .AddEntityFrameworkStores<ApplicationDbContext>()
                .AddDefaultTokenProviders();

            services.AddDbContext<Data.Parking.parkingContext>(options =>
                options.UseSqlServer(
                    Configuration.GetConnectionString("DefaultConnection")));


         services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
            services.AddHostedService<Engines.KontolerTimer>();}

最佳答案

当您使用 Visual Studio 运行它时,您可能正在使用 IIS Express,它不会运行您的 ASP.NET Core 项目,直到发出第一个请求(这实际上就是 IIS 默认的工作方式)。这适用于使用 ASP.NET Core 2.2 新增的 InProcess 托管模型,我希望您必须使用它才能看到此问题。看这个GitHub issue了解更多。

您可以通过从用于托管 ASP.NET Core 应用程序的 .csproj 文件中删除 AspNetCoreHostingModel XML 元素来证明这一理论(这会将其切换回 OutOfProcess 模式)。在 VS2017 的项目属性对话框中,“调试”下似乎有一个“托管模型”选项,如果您不想直接编辑 .csproj,可以将其更改为“进程外”。

如果您希望托管模型仅针对生产站点是进程外的,您可以使用 Web.config 转换,例如。如果您希望它在开发和生产过程中都处于进程外,只需更改我在上面调用的属性就足够了,因为它会自动转换为 Web.config 属性。如果您更愿意使用进程内模型,则在 IIS 应用程序中启用预加载是一个不错的选择(描述 here)。

关于c# - 如何在没有 http 请求的情况下在 MVC 核心应用程序中启动 HostedService,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54212990/

相关文章:

c# - 使用 TLS 1.2 从 HttpClient 连接到 Azure FrontDoor 后面的 API

c# - 使用 List、Lookup 或 Dictionary 获取大量数据

c# - 具有范围托管服务的 Entity Framework

c# - 如何从 ExecuteAsync 的代码中取消 dotnet 核心工作进程?

c# - 项目中的依赖Twilio不支持框架DNXCore,版本=v5.0

c# - 后台服务/ worker 不进行垃圾收集

c# - EF 中的 DbContext 是否应该具有较短的生命周期?

c# - Addforce 不会击退我的玩家角色

jquery - 当我在 ASP.NET Core 中发送多个属性时,如何使用 Ajax 将数据发布到 Controller 模型?

c# - ASP.NET Core 2.0 JWT 验证失败,出现 `Authorization failed for user: (null)` 错误