VS 2022 在 Quartz 后台作业完成之前不会在浏览器中启动 Swagger

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

我正在编写一个简单的应用程序,它将公开 API 并使用

Quartz
运行一些后台作业。应用程序必须重复运行获取作业,然后运行检查作业。当我从 VS 2022 启动时,Chrome 不会从 swagger 页面启动,直到检查作业完成第一次迭代。

这不是我太关心的事情,但它很烦人。我可以手动打开 Swagger。我以这种方式添加我的工作:

public sealed class CachingBackgroundJob : IJob
{
    private readonly ISchedulerService _schedulerService;

    public CachingBackgroundJob(ISchedulerService schedulerService)
    {
        _schedulerService = schedulerService;
    }

    public async Task Execute(IJobExecutionContext context)
    {
        await _schedulerService.FillCache(context.CancellationToken);
    }
}
public sealed class SchedulingBackgroundJob : IJob
{
    private readonly ISchedulerService _schedulerService;

    public SchedulingBackgroundJob(ISchedulerService schedulerService)
    {
        _schedulerService = schedulerService;
    }

    public async Task Execute(IJobExecutionContext context)
    {
        await _schedulerService.CheckHealth(context.CancellationToken);
    }
}

这些就是工作。然后,我编写了以下 DI 方法:

public static class DependencyInjection
{
    public static void AddScheduler(this IServiceCollection services)
    {
        services.AddQuartz(opts =>
        {
            var cachingBackgroundJobKey = JobKey.Create(nameof(CachingBackgroundJob));
            opts.AddJob<CachingBackgroundJob>(cachingBackgroundJobKey)
                .AddTrigger(trigger =>
                {
                    trigger.ForJob(cachingBackgroundJobKey)
                        .WithSimpleSchedule(schedule =>
                        {
                            schedule.WithRepeatCount(0);
                        });
                });
            var matcher = KeyMatcher<JobKey>.KeyEquals(cachingBackgroundJobKey);
            opts.AddJobListener<CachingJobCompletionListener>(matcher);
        });

        services.AddQuartzHostedService();
    }
}

第一个作业结束时的监听器:

internal class CachingJobCompletionListener : IJobListener
{
    public string Name => "CachingBackgroundJobCompletedListener";

    public Task JobExecutionVetoed(IJobExecutionContext context, CancellationToken cancellationToken = default)
    {
        return Task.CompletedTask;
    }

    public Task JobToBeExecuted(IJobExecutionContext context, CancellationToken cancellationToken = default)
    {
        return Task.CompletedTask;
    }

    public async Task JobWasExecuted(IJobExecutionContext context, JobExecutionException? jobException, CancellationToken cancellationToken = default)
    {
        var scheduler = context.Scheduler;
        var schedulingBackgroundJobTrigger = TriggerBuilder.Create()
            .WithSimpleSchedule(schedule =>
            {
                schedule.WithIntervalInMinutes(1);
                schedule.RepeatForever();
            })
            .StartNow()
            .Build();

        var jobDetail = JobBuilder
            .Create()
            .OfType<SchedulingBackgroundJob>()
            .WithIdentity(JobKey.Create(nameof(SchedulingBackgroundJob)))
            .DisallowConcurrentExecution()
            .Build();

        await scheduler.ScheduleJob(jobDetail, schedulingBackgroundJobTrigger, cancellationToken);
    }
}

您知道为什么这会阻止 VS 2022 启动浏览器吗? 谢谢你。

编辑:Program.cs:

var builder = WebApplication.CreateBuilder(args);

builder.Configuration.AddEnvironmentVariables();

builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

builder.Services.AddRouting(options => options.LowercaseUrls = true);

IConfiguration redisConfiguration = builder.Configuration.GetSection("Caching");
string connectionString = redisConfiguration["redis"]!;
builder.Services.AddSingleton<IConnectionMultiplexer>((serviceProvider) => ConnectionMultiplexer.Connect(connectionString));

ThreadPool.SetMinThreads(100, 100);

builder.Services.AddScoped<ISchedulerService, SchedulerService>();

builder.Services.AddHttpClient();
builder.Services.AddScheduler();

builder.Host.UseSerilog((context, config) =>
{
    config.ReadFrom.Configuration(context.Configuration);
});

var applicationAssembly = AppDomain.CurrentDomain.Load("Example.Application");

builder.Services
    .AddMediatR(opts => opts.RegisterServicesFromAssembly(applicationAssembly))
    .AddFluentValidationAutoValidation()
    .AddValidatorsFromAssembly(applicationAssembly);
ValidatorOptions.Global.DefaultRuleLevelCascadeMode = CascadeMode.Stop;

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseSerilogRequestLogging();
app.UseAuthorization();
app.MapControllers();

app.Run();

c# .net-core quartz.net
1个回答
0
投票

关于为什么这会阻止 VS 启动浏览器的任何想法 2022 年?

如果你看一下这个语句

services.AddQuartzHostedService();
,它基本上是注册一个
IHostedService
类型的QuartzHostedService。 对于
IHostedServices
,这是默认行为,并且是 .NET 6 设计的,当您调用
app.run
时,所有托管服务都会在 Kestrel Web 服务器启动之前启动。

使用 WebApplicationBuilder 时顺序不同 服务 IHostedService 实例始终在服务器启动之前运行。

问题#38698

© www.soinside.com 2019 - 2024. All rights reserved.