[英]Context is disposed when triggering Quartz job in Asp.NET core
我正在嘗試從.NET核心中的Web API控制器構建觸發器Quartz作業。 我已經成功地從Startup類使用簡單的時間表創建了一個觸發器:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IServiceProvider services)
{
loggerFactory.AddConsole(this.Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.UseCors("CorsPolicy");
app.UseApplicationInsightsRequestTelemetry();
app.UseApplicationInsightsExceptionTelemetry();
app.UseMvc();
ProcessTracksScheduler.Start(services);
}
這是啟動方法:
public static class ProcessTracksScheduler
{
public static void Start(IServiceProvider provider)
{
try
{
ISchedulerFactory schedFact = new StdSchedulerFactory();
IScheduler sched = schedFact.GetScheduler();
sched.Start();
IJobDetail job = JobBuilder.Create<ProcessTracksJob>()
.WithIdentity("ProcessTracks", "Group1")
.Build();
job.JobDataMap["tracksService"] = provider.GetService(typeof(ITracksService));
job.JobDataMap["cloudService"] = provider.GetService(typeof(ICloudService));
job.JobDataMap["broadcastService"] = provider.GetService(typeof(IBroadcastService));
job.JobDataMap["categoriesService"] = provider.GetService(typeof(ICategoriesService));
ITrigger trigger = TriggerBuilder.Create()
.WithSimpleSchedule(x => x
.RepeatForever()
.WithInterval(TimeSpan.FromDays(1)))
.StartNow()
.Build();
sched.ScheduleJob(job, trigger);
}
catch (ArgumentException e)
{
// Log the error
}
}
}
和工作:
public async void Execute(IJobExecutionContext context)
{
var tracksService = context.MergedJobDataMap["tracksService"] as ITracksService;
var cloudService = context.MergedJobDataMap["cloudService"] as ICloudService;
var broadcastService = context.MergedJobDataMap["broadcastService"] as IBroadcastService;
var categoryService = context.MergedJobDataMap["categoriesService"] as ICategoriesService;
if (tracksService == null || cloudService == null || broadcastService == null || categoryService == null)
return;
var broadcasts = broadcastService.GetAll();
// Some more work to do.
}
因此,這一功能符合預期,我對此非常滿意! 但是這里的問題是,當我試圖構建一個觸發器以使作業僅從Web API控制器啟動一次時:
[Route("Proccess")]
[HttpPost]
public async Task<IActionResult> ProccessTracks()
{
ProcessTracksScheduler.StartOnce(serviceProvider);
return Ok("Job scheduled");
}
和StartOnce方法,基本上與Start相同:
public static void StartOnce(IServiceProvider provider)
{
try
{
ISchedulerFactory schedFact = new StdSchedulerFactory();
IScheduler sched = schedFact.GetScheduler();
sched.Start();
IJobDetail job = JobBuilder.Create<ProcessTracksJob>()
.WithIdentity("ProcessTracksOnce", "Group1")
.Build();
job.JobDataMap["tracksService"] = provider.GetService(typeof(ITracksService));
job.JobDataMap["cloudService"] = provider.GetService(typeof(ICloudService));
job.JobDataMap["broadcastService"] = provider.GetService(typeof(IBroadcastService));
job.JobDataMap["categoriesService"] = provider.GetService(typeof(ICategoriesService));
ITrigger trigger = TriggerBuilder.Create()
.StartNow()
.Build();
sched.ScheduleJob(job, trigger);
}
catch (ArgumentException e)
{
// Log the error
}
}
但是在執行我的作業時,在那里var broadcasts = broadcastService.GetAll();
拋出一個異常,說我的DbContext已處置。
DbContext通過DI通過ASP.Net-Core通過DI傳遞到控制器/服務:
// In Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(this.Configuration.GetConnectionString("MyConnString")));
services.AddTransient<IBroadcastService, BroadcastsService>();
// Add the others services.
}
我嘗試了很多事情,但是找不到解決此問題的任何方法。
您是否試圖在構造函數的ProcessTracksJob
類中要求提供服務? 我這樣使用它沒有問題。
插入使用JobDataMap
如下:
public class ProcessTracksJob :IJob
{
private readonly ITracksService _tracksService;
public ProcessTracksJob(ITracksService tracksService, etc.)
{
_tracksService = tracksService;
...
}
/// the execute method using the private fields in this class
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.