我正在编写一个简单的应用程序,它将公开 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();
关于为什么这会阻止 VS 启动浏览器的任何想法 2022 年?
如果你看一下这个语句
services.AddQuartzHostedService();
,它基本上是注册一个IHostedService
类型的QuartzHostedService。
对于 IHostedServices
,这是默认行为,并且是 .NET 6 设计的,当您调用 app.run
时,所有托管服务都会在 Kestrel Web 服务器启动之前启动。
使用 WebApplicationBuilder 时顺序不同 服务 IHostedService 实例始终在服务器启动之前运行。