public static void AddJobs(this IServiceCollection services) { services.AddQuartz(q => { q.SchedulerId = "BookingScheduler"; q.UseMicrosoftDependencyInjectionScopedJobFactory(); q.UseSimpleTypeLoader(); q.UseInMemoryStore(); q.UseDefaultThreadPool(tp => { tp.MaxConcurrency = 10; }); q.ScheduleJob <BookingCheckJob>(trigger => trigger .WithIdentity("Combined Configuration Trigger") .StartAt(DateBuilder.EvenSecondDate(DateTimeOffset.UtcNow)) .WithDailyTimeIntervalSchedule(x => x.WithInterval(10, IntervalUnit.Second)) ); q.ScheduleJob <ExpiredNotificationJob>(trigger => trigger .WithIdentity("Notification users with expired terms") .StartAt(DateBuilder.EvenSecondDate(DateTimeOffset.UtcNow)) .WithDailyTimeIntervalSchedule(x => x.WithInterval(50, IntervalUnit.Second)) ); }); services.AddQuartzServer(options => { options.WaitForJobsToComplete = true; }); }
void updateJob(bool restart) { //init initSet(); if (restart) { if (!_scheduler.IsShutdown) { // _scheduler.DeleteJob(_upload_job.Key); jobflag("Wait Other Job to Complete.Please Wait.Thank Your."); _scheduler.Shutdown();//true _scheduler = StdSchedulerFactory.GetDefaultScheduler(); _scheduler.Start(); lbl0msg.Text = "Restart Success,and restart OK."; } } #region "upload" DateTimeOffset runTime = DateBuilder.EvenSecondDate(DateTimeOffset.Now); _upload_job = JobBuilder.Create <updateJob>() .WithIdentity("UploadJob", "UploadGroup") .Build(); _upload_trigger = TriggerBuilder.Create() .WithIdentity("UploadTrigger", "UploadGroup") .StartAt(runTime) .WithSimpleSchedule(x => x.WithIntervalInMinutes(_txt0Rtime).RepeatForever()) .Build(); // Tell quartz to schedule the job using our trigger _scheduler.ScheduleJob(_upload_job, _upload_trigger); #endregion "upload" }
protected override void OnStart(string[] args) { try { scheduler.Start(); AllMsg("Quartz服务成功启动."); DateTimeOffset runTime = DateBuilder.EvenSecondDate(DateTimeOffset.Now); //get #region satrtAutoGetXml job taskMin = setTaskMin(); IJobDetail AutoGetXml_job = JobBuilder.Create <AutoGetXmlJob>().WithIdentity("autoGetXMLjob", "autoGetXMLGroup").Build(); ITrigger AutoGetXml_trigger = TriggerBuilder.Create() .WithIdentity("autoGetXMLTrigger", "autoGetXMLGroup") .StartAt(runTime) .WithSimpleSchedule(x => x.WithIntervalInMinutes(taskMin).RepeatForever()) .Build(); // Tell quartz to schedule the job using our trigger scheduler.ScheduleJob(AutoGetXml_job, AutoGetXml_trigger); #endregion } catch (Exception ex) { logger.Error(ex.Message); } }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddQuartz(q => { // base quartz scheduler, job and trigger configuration q.UseMicrosoftDependencyInjectionJobFactory(); q.UseSimpleTypeLoader(); q.UseInMemoryStore(); q.UseDefaultThreadPool(tp => { tp.MaxConcurrency = 10; }); q.ScheduleJob <ReportJob>(trigger => trigger .WithIdentity("Combined Configuration Trigger") .StartAt(DateBuilder.EvenSecondDate(DateTimeOffset.UtcNow.AddSeconds(7))) .WithDailyTimeIntervalSchedule(x => x.WithInterval(1, IntervalUnit.Minute)) .WithDescription("my awesome trigger configured for a job with single call") ); }); // ASP.NET Core hosting services.AddQuartzServer(options => { // when shutting down we want jobs to complete gracefully options.WaitForJobsToComplete = true; }); services.AddRazorPages(); services.AddControllersWithViews(); services.AddDbContext <PlannerContext>(options => { if (options == null) { throw new ArgumentNullException(nameof(options)); } options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")); }); services.AddIdentity <IdentityUser, IdentityRole>().AddEntityFrameworkStores <PlannerContext>(); services.Configure <IdentityOptions>(options => { options.Password.RequiredLength = 4; options.Password.RequireNonAlphanumeric = false; options.Password.RequireDigit = false; }); services.AddAzureClients(builder => { builder.AddBlobServiceClient(Configuration["plannerconnstring:blob"], preferMsi: true); builder.AddQueueServiceClient(Configuration["plannerconnstring:queue"], preferMsi: true); }); }
public void TestGetFireTimeAfter() { SimpleTriggerImpl simpleTrigger = new SimpleTriggerImpl(); DateTimeOffset startTime = DateBuilder.EvenSecondDate(DateTime.UtcNow); simpleTrigger.StartTimeUtc = startTime; simpleTrigger.RepeatInterval = TimeSpan.FromMilliseconds(10); simpleTrigger.RepeatCount = 4; DateTimeOffset?fireTimeAfter; fireTimeAfter = simpleTrigger.GetFireTimeAfter(startTime.AddMilliseconds(34)); Assert.AreEqual(startTime.AddMilliseconds(40), fireTimeAfter.Value); }
public async Task <IHttpActionResult> RerunEdfTask([FromUri] string scheduledTime) { try { //DateTime scheduled; //= DateTime.Now; //scheduledTime = DateTime.Now.AddSeconds(5).ToString(); //DateTime.TryParse(scheduledTime, out scheduled); job = JobBuilder.Create <MonitorBehaviorJob>() .WithIdentity("TestTask", "group1") .UsingJobData("Name", "Test Task") .Build(); jobTrigger = (TriggerBuilder.Create() .WithIdentity("SimpleTrigger", "group1") .StartAt(DateBuilder.EvenSecondDate(DateTimeOffset.UtcNow)) .Build()) as ISimpleTrigger; if (_scheduler.IsStarted) { await _scheduler.UnscheduleJob(jobTrigger.Key); } else { await _scheduler.Start(); } //DateTimeOffset scheduled = DateTimeOffset.UtcNow.AddSeconds(5); var runtime = await _scheduler.ScheduleJob(job, jobTrigger); //var localRunTime = runtime. Debug.WriteLine($"The task will run at {runtime}"); return(Ok()); } catch { return(InternalServerError()); } }
public static async Task StartAsync <T>(string cronExp, string jobName, string triggerName, string groupName, AppEntity appEntity) where T : IJob { JobDataMap jobDataMap = new JobDataMap(); jobDataMap.Put("AppEntity", appEntity); DateTimeOffset runTime = DateBuilder.EvenSecondDate(DateTime.Now); IJobDetail job = JobBuilder.Create <T>().WithIdentity(jobName, groupName).UsingJobData(jobDataMap).Build(); ITrigger trigger = TriggerBuilder.Create().WithIdentity(triggerName, groupName).WithCronSchedule(cronExp) .StartAt(runTime).Build(); ISchedulerFactory factory = new StdSchedulerFactory(); IScheduler scheduler = await factory.GetScheduler(); await scheduler.ScheduleJob(job, trigger); await scheduler.Start(); }
public static async Task StartAsync <T>(TimeSpan ts, string jobName, string triggerName, string groupName, AppEntity appEntity) where T : IJob { JobDataMap jobDataMap = new JobDataMap(); jobDataMap.Put("AppEntity", appEntity); DateTimeOffset runTime = DateBuilder.EvenSecondDate(DateTime.Now); IJobDetail job = JobBuilder.Create <T>().WithIdentity(jobName, groupName).UsingJobData(jobDataMap).Build(); ITrigger trigger = TriggerBuilder.Create().WithIdentity(triggerName, groupName).StartAt(runTime) .WithSimpleSchedule(x => x.WithInterval(ts).RepeatForever()).Build(); ISchedulerFactory factory = new StdSchedulerFactory(); IScheduler scheduler = await factory.GetScheduler(); scheduler.Context.Put("AppEntity", appEntity); await scheduler.ScheduleJob(job, trigger); await scheduler.Start(); }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddHttpClient(); services.AddDbContext <BrowserVersionsContext>(); services.AddScoped <IBrowserVersionService, BrowserVersionService>(); services.AddScoped <IBrowserVersionSeedingService, BrowserVersionSeedingService>(); services.AddTransient <BrowserVersionUpdateJob>(); services.AddControllers(); services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "BrowserVersions.API", Version = "v1" }); }); services.AddQuartz(q => { // base quartz scheduler, job and trigger configuration q.UseMicrosoftDependencyInjectionJobFactory(); q.UseSimpleTypeLoader(); q.UseInMemoryStore(); q.UseDefaultThreadPool(tp => { tp.MaxConcurrency = 10; }); q.ScheduleJob <BrowserVersionUpdateJob>(trigger => trigger .WithIdentity("Data Update Trigger") .StartAt(DateBuilder.EvenSecondDate(DateTimeOffset.UtcNow.AddSeconds(7))) .WithDailyTimeIntervalSchedule(x => x.WithInterval(12, IntervalUnit.Hour)) .WithDescription("Job that fetches the latest versions from all apis and inserts new data to the database") ); }); // ASP.NET Core hosting services.AddQuartzServer(options => { // when shutting down we want jobs to complete gracefully options.WaitForJobsToComplete = true; }); }
public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .UseSerilog() .ConfigureServices((hostContext, services) => { services.AddHostedService <Worker>(); // if you are using persistent job store, you might want to alter some options services.Configure <QuartzOptions>(options => { options.Scheduling.IgnoreDuplicates = true; // default: false options.Scheduling.OverWriteExistingData = true; // default: true }); // base configuration for DI services.AddQuartz(q => { // handy when part of cluster or you want to otherwise identify multiple schedulers q.SchedulerId = "Scheduler-Core"; // we take this from appsettings.json, just show it's possible // q.SchedulerName = "Quartz ASP.NET Core Sample Scheduler"; // this is default configuration if you don't alter it q.UseMicrosoftDependencyInjectionJobFactory(); // these are the defaults q.UseSimpleTypeLoader(); q.UseInMemoryStore(); q.UseDefaultThreadPool(tp => { tp.MaxConcurrency = 10; }); // quickest way to create a job with single trigger is to use ScheduleJob q.ScheduleJob <ExampleJob>(trigger => trigger .WithIdentity("Combined Configuration Trigger") .StartAt(DateBuilder.EvenSecondDate(DateTimeOffset.UtcNow.AddSeconds(7))) .WithDailyTimeIntervalSchedule(x => x.WithInterval(10, IntervalUnit.Second)) .WithDescription("my awesome trigger configured for a job with single call") ); // configure jobs with code var jobKey = new JobKey("awesome job", "awesome group"); q.AddJob <ExampleJob>(j => j .StoreDurably() .WithIdentity(jobKey) .WithDescription("my awesome job") ); q.AddTrigger(t => t .WithIdentity("Simple Trigger") .ForJob(jobKey) .StartNow() .WithSimpleSchedule(x => x.WithInterval(TimeSpan.FromSeconds(10)).RepeatForever()) .WithDescription("my awesome simple trigger") ); }); // Quartz.Extensions.Hosting hosting services.AddQuartzHostedService(options => { // when shutting down we want jobs to complete gracefully options.WaitForJobsToComplete = true; // when we need to init another IHostedServices first options.StartDelay = TimeSpan.FromSeconds(10); }); });
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { // make sure you configure logging and open telemetry before quartz services services.AddLogging(loggingBuilder => { loggingBuilder.ClearProviders(); loggingBuilder.AddSerilog(dispose: true); }); services.AddOpenTelemetryTracing(builder => { builder .AddQuartzInstrumentation() .AddZipkinExporter(o => { o.Endpoint = new Uri("http://localhost:9411/api/v2/spans"); o.ServiceName = "Quartz.Examples.AspNetCore"; }) .AddJaegerExporter(o => { o.ServiceName = "Quartz.Examples.AspNetCore"; // these are the defaults o.AgentHost = "localhost"; o.AgentPort = 6831; }); }); services.AddRazorPages(); // base configuration for DI services.Configure <QuartzOptions>(Configuration.GetSection("Quartz")); services.AddQuartz(q => { // handy when part of cluster or you want to otherwise identify multiple schedulers q.SchedulerId = "Scheduler-Core"; // we take this from appsettings.json, just show it's possible // q.SchedulerName = "Quartz ASP.NET Core Sample Scheduler"; // we could leave DI configuration intact and then jobs need to have public no-arg constructor // the MS DI is expected to produce transient job instances q.UseMicrosoftDependencyInjectionJobFactory(options => { // if we don't have the job in DI, allow fallback to configure via default constructor options.AllowDefaultConstructor = true; }); // or // q.UseMicrosoftDependencyInjectionScopedJobFactory(); // these are the defaults q.UseSimpleTypeLoader(); q.UseInMemoryStore(); q.UseDefaultThreadPool(tp => { tp.MaxConcurrency = 10; }); // quickest way to create a job with single trigger is to use ScheduleJob q.ScheduleJob <ExampleJob>(trigger => trigger .WithIdentity("Combined Configuration Trigger") .StartAt(DateBuilder.EvenSecondDate(DateTimeOffset.UtcNow.AddSeconds(7))) .WithDailyTimeIntervalSchedule(x => x.WithInterval(10, IntervalUnit.Second)) .WithDescription("my awesome trigger configured for a job with single call") ); // you can also configure individual jobs and triggers with code // this allows you to associated multiple triggers with same job // (if you want to have different job data map per trigger for example) q.AddJob <ExampleJob>(j => j .StoreDurably() // we need to store durably if no trigger is associated .WithDescription("my awesome job") ); // here's a known job for triggers var jobKey = new JobKey("awesome job", "awesome group"); q.AddJob <ExampleJob>(jobKey, j => j .WithDescription("my awesome job") ); q.AddTrigger(t => t .WithIdentity("Simple Trigger") .ForJob(jobKey) .StartNow() .WithSimpleSchedule(x => x.WithInterval(TimeSpan.FromSeconds(10)).RepeatForever()) .WithDescription("my awesome simple trigger") ); q.AddTrigger(t => t .WithIdentity("Cron Trigger") .ForJob(jobKey) .StartAt(DateBuilder.EvenSecondDate(DateTimeOffset.UtcNow.AddSeconds(3))) .WithCronSchedule("0/3 * * * * ?") .WithDescription("my awesome cron trigger") ); const string calendarName = "myHolidayCalendar"; q.AddCalendar <HolidayCalendar>( name: calendarName, replace: true, updateTriggers: true, x => x.AddExcludedDate(new DateTime(2020, 5, 15)) ); q.AddTrigger(t => t .WithIdentity("Daily Trigger") .ForJob(jobKey) .StartAt(DateBuilder.EvenSecondDate(DateTimeOffset.UtcNow.AddSeconds(5))) .WithDailyTimeIntervalSchedule(x => x.WithInterval(10, IntervalUnit.Second)) .WithDescription("my awesome daily time interval trigger") .ModifiedByCalendar(calendarName) ); // also add XML configuration and poll it for changes q.UseXmlSchedulingConfiguration(x => { x.Files = new[] { "~/quartz_jobs.config" }; x.ScanInterval = TimeSpan.FromMinutes(1); x.FailOnFileNotFound = true; x.FailOnSchedulingError = true; }); // convert time zones using converter that can handle Windows/Linux differences q.UseTimeZoneConverter(); // add some listeners q.AddSchedulerListener <SampleSchedulerListener>(); q.AddJobListener <SampleJobListener>(GroupMatcher <JobKey> .GroupEquals(jobKey.Group)); q.AddTriggerListener <SampleTriggerListener>(); // example of persistent job store using JSON serializer as an example /* * q.UsePersistentStore(s => * { * s.UseProperties = true; * s.RetryInterval = TimeSpan.FromSeconds(15); * s.UseSqlServer(sqlServer => * { * sqlServer.ConnectionString = "some connection string"; * // this is the default * sqlServer.TablePrefix = "QRTZ_"; * }); * s.UseJsonSerializer(); * s.UseClustering(c => * { * c.CheckinMisfireThreshold = TimeSpan.FromSeconds(20); * c.CheckinInterval = TimeSpan.FromSeconds(10); * }); * }); */ }); // we can use options pattern to support hooking your own configuration with Quartz's // because we don't use service registration api, we need to manally ensure the job is present in DI services.AddTransient <ExampleJob>(); services.Configure <SampleOptions>(Configuration.GetSection("Sample")); services.AddOptions <QuartzOptions>() .Configure <IOptions <SampleOptions> >((options, dep) => { if (!string.IsNullOrWhiteSpace(dep.Value.CronSchedule)) { var jobKey = new JobKey("options-custom-job", "custom"); options.AddJob <ExampleJob>(j => j.WithIdentity(jobKey)); options.AddTrigger(trigger => trigger .WithIdentity("options-custom-trigger", "custom") .ForJob(jobKey) .WithCronSchedule(dep.Value.CronSchedule)); } }); // ASP.NET Core hosting services.AddQuartzServer(options => { // when shutting down we want jobs to complete gracefully options.WaitForJobsToComplete = true; }); services .AddHealthChecksUI() .AddInMemoryStorage(); }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddRazorPages(); // easier to see behavior with timestamps services.AddLogging(opt => { opt.AddConsole(c => { c.TimestampFormat = "[HH:mm:ss] "; }); }); // base configuration for DI services.AddQuartz(q => { // handy when part of cluster or you want to otherwise identify multiple schedulers q.SchedulerId = "Scheduler-Core"; // we take this from appsettings.json, just show it's possible // q.SchedulerName = "Quartz ASP.NET Core Sample Scheduler"; // hooks LibLog to Microsoft logging without allowing it to detect concrete implementation // if you are using NLog, SeriLog or log4net you shouldn't need this q.UseQuartzMicrosoftLoggingBridge(); // we could leave DI configuration intact and then jobs need to have public no-arg constructor // the MS DI is expected to produce transient job instances q.UseMicrosoftDependencyInjectionJobFactory(options => { // if we don't have the job in DI, allow fallback to configure via default constructor options.AllowDefaultConstructor = true; }); // or // q.UseMicrosoftDependencyInjectionScopedJobFactory(); // these are the defaults q.UseSimpleTypeLoader(); q.UseInMemoryStore(); q.UseDefaultThreadPool(tp => { tp.ThreadCount = 10; }); // configure jobs with code var jobKey = new JobKey("awesome job", "awesome group"); q.AddJob <ExampleJob>(j => j .StoreDurably() .WithIdentity(jobKey) .WithDescription("my awesome job") ); q.AddTrigger(t => t .WithIdentity("Simple Trigger") .ForJob(jobKey) .StartNow() .WithSimpleSchedule(x => x.WithInterval(TimeSpan.FromSeconds(10)).RepeatForever()) .WithDescription("my awesome simple trigger") ); q.AddTrigger(t => t .WithIdentity("Cron Trigger") .ForJob(jobKey) .StartAt(DateBuilder.EvenSecondDate(DateTimeOffset.UtcNow.AddSeconds(3))) .WithCronSchedule("0/3 * * * * ?") .WithDescription("my awesome cron trigger") ); q.AddTrigger(t => t .WithIdentity("Daily Trigger") .ForJob(jobKey) .StartAt(DateBuilder.EvenSecondDate(DateTimeOffset.UtcNow.AddSeconds(5))) .WithDailyTimeIntervalSchedule(x => x.WithInterval(10, IntervalUnit.Second)) .WithDescription("my awesome daily time interval trigger") ); // also add XML configuration and poll it for changes q.UseXmlSchedulingConfiguration(x => { x.Files = new[] { "~/quartz_jobs.config" }; x.ScanInterval = TimeSpan.FromSeconds(2); x.FailOnFileNotFound = true; x.FailOnSchedulingError = true; }); // convert time zones using converter that can handle Windows/Linux differences q.UseTimeZoneConverter(); // add some listeners q.AddSchedulerListener <SampleSchedulerListener>(); q.AddJobListener <SampleJobListener>(GroupMatcher <JobKey> .GroupEquals(jobKey.Group)); q.AddTriggerListener <SampleTriggerListener>(); // example of persistent job store using JSON serializer as an example /* * q.UsePersistentStore(s => * { * s.UseProperties = true; * s.RetryInterval = TimeSpan.FromSeconds(15); * s.UseSqlServer(sqlServer => * { * sqlServer.ConnectionString = "some connection string"; * // this is the default * sqlServer.TablePrefix = "QRTZ_"; * }); * s.UseJsonSerializer(); * s.UseClustering(c => * { * c.CheckinMisfireThreshold = TimeSpan.FromSeconds(20); * c.CheckinInterval = TimeSpan.FromSeconds(10); * }); * }); */ }); // ASP.NET Core hosting services.AddQuartzServer(options => { // when shutting down we want jobs to complete gracefully options.WaitForJobsToComplete = true; }); services .AddHealthChecksUI() .AddInMemoryStorage(); }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { #region Logging // make sure you configure logging and open telemetry before quartz services services.AddLogging(loggingBuilder => { loggingBuilder.ClearProviders(); loggingBuilder.AddSerilog(dispose: true); }); services.AddRazorPages(); #endregion Logging #region Quartz // base configuration for DI services.Configure <QuartzOptions>(Configuration.GetSection("Quartz")); services.AddQuartz(q => { // handy when part of cluster or you want to otherwise identify multiple schedulers q.SchedulerId = "Scheduler-Core"; #region DI Job Factory // this is default configuration if you don't alter it q.UseMicrosoftDependencyInjectionJobFactory(options => { // if we don't have the job in DI, allow fallback to configure via default constructor options.AllowDefaultConstructor = true; // set to true if you want to inject scoped services like Entity Framework's DbContext options.CreateScope = false; }); #endregion DI Job Factory #region Default Config -- For InMemory Store -- Comment if uses Persist Store -- Commented // these are the defaults //q.UseSimpleTypeLoader(); //q.UseInMemoryStore(); //q.UseDefaultThreadPool(tp => //{ // tp.MaxConcurrency = 10; //}); #endregion Default Config -- For InMemory Store -- Comment if uses Persist Store -- Commented #region Simple Trigger //// Create a job with Single Trigger //q.ScheduleJob<FirstSample>(trigger => trigger // .WithIdentity("SomeTrigger") // .StartAt(DateBuilder.EvenSecondDate(DateTimeOffset.UtcNow.AddSeconds(5))) // .WithDailyTimeIntervalSchedule(x => x.WithInterval(10, IntervalUnit.Second)) // .WithDescription("Say somethign Trigger configured for a SaySomethingJob with single call") // ); #endregion Simple Trigger #region Configure Individual Jobs And Trigger -- Commented // you can also configure individual jobs and triggers with code // this allows you to associated multiple triggers with same job // (if you want to have different job data map per trigger for example) //q.AddJob<ExampleJob>(j => j // .StoreDurably() // we need to store durably if no trigger is associated // .WithDescription("my awesome job") //); #endregion Configure Individual Jobs And Trigger -- Commented #region Second Sample Job with SampleTrigger and CronTrigger var secondSampleJobKey = new JobKey("Second Sample Job", "Sample Job Group"); q.AddJob <SecondSample>(secondSampleJobKey, j => j.WithDescription("My Second Sample Job")); // Sample Trigger for Second Sample Job q.AddTrigger(trigger => trigger .WithIdentity("SecondSample Sample Trigger") .ForJob(secondSampleJobKey) .StartNow() .WithSimpleSchedule(x => x.WithInterval(TimeSpan.FromSeconds(7)).RepeatForever()) .WithDescription("My Second Sample Trigger") ); // Cron Trigger for Second Sample Job q.AddTrigger(trigger => trigger .WithIdentity("My Second Sample Cron Trigger") .ForJob(secondSampleJobKey) .StartAt(DateBuilder.EvenSecondDate(DateTimeOffset.UtcNow.AddSeconds(3))) .WithCronSchedule("0/17 * * * * ?") .WithDescription("My Second Cron Trigger") ); #endregion Second Sample Job with SampleTrigger and CronTrigger #region TimeConverter q.UseTimeZoneConverter(); #endregion TimeConverter #region Sample Listener // Add Second Sample Listener q.AddJobListener <SecondSampleJobListener>(GroupMatcher <JobKey> .GroupEquals(secondSampleJobKey.Group)); q.AddTriggerListener <SecondSampleTriggerListener>(); q.AddSchedulerListener <SecondSampleSchedulerListener>(); #endregion Sample Listener #region Job Using Data var dataJobKey = new JobKey("AuthorInfo", "Using Data Group"); q.AddJob <UsingDataJob>(options => options.WithIdentity(dataJobKey) .UsingJobData("Name", "Nguyen Minh Van") .UsingJobData("Age", "24") .UsingJobData("Address", "District 12, Ho Chi Minh City") ); q.AddTrigger(options => options.ForJob(dataJobKey) .WithIdentity("DataJob-Trigger") .WithCronSchedule("0/5 * * * * ?")); #endregion Job Using Data #region Calender //const string calendarName = "myHolidayCalendar"; //q.AddCalendar<HolidayCalendar>( // name: calendarName, // replace: true, // updateTriggers: true, // x => x.AddExcludedDate(new DateTime(2020, 5, 15)) //); //q.AddTrigger(t => t // .WithIdentity("Daily Trigger") // .ForJob(jobKey) // .StartAt(DateBuilder.EvenSecondDate(DateTimeOffset.UtcNow.AddSeconds(5))) // .WithDailyTimeIntervalSchedule(x => x.WithInterval(10, IntervalUnit.Second)) // .WithDescription("my awesome daily time interval trigger") // .ModifiedByCalendar(calendarName) //); // convert time zones using converter that can handle Windows/Linux differences //q.UseTimeZoneConverter(); #endregion Calender }); #endregion Quartz #region Quartz Options // we can use options pattern to support hooking your own configuration with Quartz's // because we don't use service registration api, we need to manally ensure the job is present in DI //services.AddTransient<ExampleJob>(); //services.Configure<SampleOptions>(Configuration.GetSection("Sample")); //services.AddOptions<QuartzOptions>() // .Configure<IOptions<SampleOptions>>((options, dep) => // { // if (!string.IsNullOrWhiteSpace(dep.Value.CronSchedule)) // { // var jobKey = new JobKey("options-custom-job", "custom"); // options.AddJob<ExampleJob>(j => j.WithIdentity(jobKey)); // options.AddTrigger(trigger => trigger // .WithIdentity("options-custom-trigger", "custom") // .ForJob(jobKey) // .WithCronSchedule(dep.Value.CronSchedule)); // } // }); #endregion Quartz Options #region Quartz Server // ASP.NET Core hosting services.AddQuartzServer(options => { // when shutting down we want jobs to complete gracefully options.WaitForJobsToComplete = true; }); #endregion Quartz Server #region Other Services services .AddHealthChecksUI() .AddInMemoryStorage(); #endregion Other Services }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { // make sure you configure logging and open telemetry before quartz services services.AddLogging(loggingBuilder => { loggingBuilder.ClearProviders(); loggingBuilder.AddSerilog(dispose: true); }); services.AddOpenTelemetry(builder => { builder .AddQuartzInstrumentation() .UseZipkinExporter(o => { o.Endpoint = new Uri("http://localhost:9411/api/v2/spans"); o.ServiceName = "Quartz.Examples.AspNetCore"; }) .UseJaegerExporter(o => { o.ServiceName = "Quartz.Examples.AspNetCore"; // these are the defaults o.AgentHost = "localhost"; o.AgentPort = 6831; }); }); services.AddRazorPages(); // base configuration for DI services.AddQuartz(q => { // handy when part of cluster or you want to otherwise identify multiple schedulers q.SchedulerId = "Scheduler-Core"; // we take this from appsettings.json, just show it's possible // q.SchedulerName = "Quartz ASP.NET Core Sample Scheduler"; // we could leave DI configuration intact and then jobs need to have public no-arg constructor // the MS DI is expected to produce transient job instances q.UseMicrosoftDependencyInjectionJobFactory(options => { // if we don't have the job in DI, allow fallback to configure via default constructor options.AllowDefaultConstructor = true; }); // or // q.UseMicrosoftDependencyInjectionScopedJobFactory(); // these are the defaults q.UseSimpleTypeLoader(); q.UseInMemoryStore(); q.UseDefaultThreadPool(tp => { tp.MaxConcurrency = 10; }); // configure jobs with code var jobKey = new JobKey("awesome job", "awesome group"); q.AddJob <ExampleJob>(j => j .StoreDurably() .WithIdentity(jobKey) .WithDescription("my awesome job") ); q.AddTrigger(t => t .WithIdentity("Simple Trigger") .ForJob(jobKey) .StartNow() .WithSimpleSchedule(x => x.WithInterval(TimeSpan.FromSeconds(10)).RepeatForever()) .WithDescription("my awesome simple trigger") ); q.AddTrigger(t => t .WithIdentity("Cron Trigger") .ForJob(jobKey) .StartAt(DateBuilder.EvenSecondDate(DateTimeOffset.UtcNow.AddSeconds(3))) .WithCronSchedule("0/3 * * * * ?") .WithDescription("my awesome cron trigger") ); q.AddTrigger(t => t .WithIdentity("Daily Trigger") .ForJob(jobKey) .StartAt(DateBuilder.EvenSecondDate(DateTimeOffset.UtcNow.AddSeconds(5))) .WithDailyTimeIntervalSchedule(x => x.WithInterval(10, IntervalUnit.Second)) .WithDescription("my awesome daily time interval trigger") ); // also add XML configuration and poll it for changes q.UseXmlSchedulingConfiguration(x => { x.Files = new[] { "~/quartz_jobs.config" }; x.ScanInterval = TimeSpan.FromMinutes(1); x.FailOnFileNotFound = true; x.FailOnSchedulingError = true; }); // convert time zones using converter that can handle Windows/Linux differences q.UseTimeZoneConverter(); // add some listeners q.AddSchedulerListener <SampleSchedulerListener>(); q.AddJobListener <SampleJobListener>(GroupMatcher <JobKey> .GroupEquals(jobKey.Group)); q.AddTriggerListener <SampleTriggerListener>(); // example of persistent job store using JSON serializer as an example /* * q.UsePersistentStore(s => * { * s.UseProperties = true; * s.RetryInterval = TimeSpan.FromSeconds(15); * s.UseSqlServer(sqlServer => * { * sqlServer.ConnectionString = "some connection string"; * // this is the default * sqlServer.TablePrefix = "QRTZ_"; * }); * s.UseJsonSerializer(); * s.UseClustering(c => * { * c.CheckinMisfireThreshold = TimeSpan.FromSeconds(20); * c.CheckinInterval = TimeSpan.FromSeconds(10); * }); * }); */ }); // ASP.NET Core hosting services.AddQuartzServer(options => { // when shutting down we want jobs to complete gracefully options.WaitForJobsToComplete = true; }); services .AddHealthChecksUI() .AddInMemoryStorage(); }
public static void ConfigureServices(IServiceCollection services) { services.AddQuartz(configurator => { // handy when part of cluster or you want to otherwise identify multiple schedulers configurator.SchedulerId = "my_scheduler"; // we take this from appsettings.json, just show it's possible // q.SchedulerName = "Quartz ASP.NET Core Sample Scheduler"; // we could leave DI configuration intact and then jobs need to have public no-arg constructor // the MS DI is expected to produce transient job instances configurator.UseMicrosoftDependencyInjectionJobFactory(options => { // if we don't have the job in DI, allow fallback to configure via default constructor options.AllowDefaultConstructor = true; }); // or // q.UseMicrosoftDependencyInjectionScopedJobFactory(); // these are the defaults configurator.UseSimpleTypeLoader(); configurator.UseInMemoryStore(); configurator.UseDefaultThreadPool(tp => { tp.MaxConcurrency = 10; }); //// quickest way to create a job with single trigger is to use ScheduleJob (requires version 3.2) //configure.ScheduleJob<MyJob>(trigger => trigger // .WithIdentity("Combined Configuration Trigger") // .StartAt(DateBuilder.EvenSecondDate(DateTimeOffset.UtcNow.AddSeconds(7))) // .WithDailyTimeIntervalSchedule(x => x.WithInterval(10, IntervalUnit.Second)) // .WithDescription("my awesome trigger configured for a job with single call") //); //// you can also configure individual jobs and triggers with code //// this allows you to associated multiple triggers with same job //// (if you want to have different job data map per trigger for example) //configure.AddJob<ExampleJob>(j => j // .StoreDurably() // we need to store durably if no trigger is associated // .WithDescription("my awesome job") //); // here's a known job for triggers var jobKey = new JobKey("awesome job", "awesome group"); configurator.AddJob <MyJob>(jobKey, j => j .WithDescription("my awesome job") ); configurator.AddTrigger(t => t .WithIdentity("Simple Trigger") .ForJob(jobKey) .StartNow() .WithSimpleSchedule(x => x.WithInterval(TimeSpan.FromSeconds(10)).RepeatForever()) .WithDescription("my awesome simple trigger") ); configurator.AddTrigger(t => t .WithIdentity("Cron Trigger") .ForJob(jobKey) .StartAt(DateBuilder.EvenSecondDate(DateTimeOffset.UtcNow.AddSeconds(3))) .WithCronSchedule("0/3 * * * * ?") .WithDescription("my awesome cron trigger") ); //// you can add calendars too (requires version 3.2) //const string calendarName = "myHolidayCalendar"; //configure.AddCalendar<HolidayCalendar>( // name: calendarName, // replace: true, // updateTriggers: true, // x => x.AddExcludedDate(new DateTime(2020, 5, 15)) //); configurator.AddTrigger(t => t .WithIdentity("Daily Trigger") .ForJob(jobKey) .StartAt(DateBuilder.EvenSecondDate(DateTimeOffset.UtcNow.AddSeconds(5))) .WithDailyTimeIntervalSchedule(x => x.WithInterval(10, IntervalUnit.Second)) .WithDescription("my awesome daily time interval trigger") .ModifiedByCalendar(calendarName) ); //// also add XML configuration and poll it for changes //configure.UseXmlSchedulingConfiguration(x => //{ // x.Files = new[] { "~/quartz_jobs.config" }; // x.ScanInterval = TimeSpan.FromSeconds(2); // x.FailOnFileNotFound = true; // x.FailOnSchedulingError = true; //}); //// convert time zones using converter that can handle Windows/Linux differences //configure.UseTimeZoneConverter(); //// add some listeners //configure.AddSchedulerListener<SampleSchedulerListener>(); //configure.AddJobListener<SampleJobListener>(GroupMatcher<JobKey>.GroupEquals(jobKey.Group)); //configure.AddTriggerListener<SampleTriggerListener>(); // example of persistent job store using JSON serializer as an example /* * q.UsePersistentStore(s => * { * s.UseProperties = true; * s.RetryInterval = TimeSpan.FromSeconds(15); * s.UseSqlServer(sqlServer => * { * sqlServer.ConnectionString = "some connection string"; * // this is the default * sqlServer.TablePrefix = "QRTZ_"; * }); * s.UseJsonSerializer(); * s.UseClustering(c => * { * c.CheckinMisfireThreshold = TimeSpan.FromSeconds(20); * c.CheckinInterval = TimeSpan.FromSeconds(10); * }); * }); */ }); }