Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在Asp.NET内核中触发Quartz作业时释放上下文_C#_Asp.net Core - Fatal编程技术网

C# 在Asp.NET内核中触发Quartz作业时释放上下文

C# 在Asp.NET内核中触发Quartz作业时释放上下文,c#,asp.net-core,C#,Asp.net Core,我正在尝试从.NETCore中的WebAPI控制器构建一个触发石英作业。 我已经成功地从启动类创建了一个具有简单计划的触发器: public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IServiceProvider services) { loggerFactory.AddConsole(this.Conf

我正在尝试从.NETCore中的WebAPI控制器构建一个触发石英作业。 我已经成功地从启动类创建了一个具有简单计划的触发器:

 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
            }
        }
   }
因此,这一个工程如预期,我很高兴与它!但这里的问题是,当我试图构建一个触发器,使作业仅从我的web API控制器启动一次时:

[Route("Proccess")]
[HttpPost]
public async Task<IActionResult> ProccessTracks()
{
    ProcessTracksScheduler.StartOnce(serviceProvider);
    return Ok("Job scheduled");
}

我尝试了很多方法,但找不到解决此问题的任何方法。

您是否尝试过在构造函数的
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

}

您的Quartz代码是否在ASP.NET应用程序中运行?如果是这样,你就不应该那样做。ASP.NET用于短时间运行的任务,然后结束。通过在其中扩展它(如运行Quartz),您违反了ASP.NET的原则。它将在其生命周期结束时终止。相反,应用程序应该与包含石英代码的专用进程通信。我的石英代码位于另一个项目中,而不是ASP.NET应用程序中。这就是你的意思吗?那个项目正在创建一个可执行文件吗?不,你说得对。quartz作业在ASP.NET应用程序中执行。但现在这并不是一个真正的问题,这项工作一点也不繁重。不管它有多繁重,你都无法控制ASP.NET和IIS何时会回收应用程序池,或者任何数量的可能性。任何超过几秒钟的运行都有可能被终止。因此,正如您所想象的那样,试图在将来安排一整天的时间来运行某些东西是行不通的。如果您的类是从
IJob
派生的,那么它将毫无问题地执行该方法。此外,请记住在DI库中注册它,以便能够将这些服务注入构造函数中。我使用这种方法没有问题。是否有任何错误?完全没有错误,请在execute方法中放置一个断点,但它不会命中它。。在我的DI库中注册它,您的意思是这样的:
services.AddTransient()
ConfigureService(IServiceCollection服务)
方法中?对于DI,我使用的作业类如下:
builder.RegisterType().AsSelf()(自动传真)。石英配置对我来说是一样的。对于测试,我使用较小的触发器时间跨度。我不希望使用Autofac,因为Asp.NET-core已经处理DI…可能是生命周期已过期,您是否尝试过不同的生命周期服务?(范围限定,单例)
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
    }
}
// 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.        
}
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

}