簡體   English   中英

在Asp.NET Core中觸發Quartz作業時處理上下文

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM