Detailed. NET Core uses Quartz to perform scheduling task escalation

Time:2019-8-12

I. Preface Scene

Quartz. Net is a powerful, open source, lightweight job scheduling framework. It also needs to be used in the regular project development from time to time. For example, it needs to count the data of the previous day in the morning, or the data of last month at the beginning of each month. Of course, there will also be statistical days and months, but also need to carry out other operations. So how can we write such a scheduling task?

II. Practical application (.Net Core 2.2)

In a solution, create a. Net console application and a class library, and the console application is used as the starting point of the program. Class libraries are used as execution programs for scheduling tasks.

Then we need to improve the structure of the project. First, we need to create a Startup class in the console application, which is also an important condition for task startup.


public class Startup
  {

    public Startup(IConfiguration configuration)
    {

      Configuration = configuration;

    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.

    public void ConfigureServices(IServiceCollection services)
    {

      services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

    }

 

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {

      if (env.IsDevelopment())
      {
        app.UseDeveloperExceptionPage();
      }
      else
      {
        app.UseExceptionHandler("/Error");
      }
      app.UseMvc();
    }
  }

Then the project will report some errors and solve them step by step according to the error information. The solution is to add the NuGet package Microsoft. AspNetCore.

After resolving the error message, it means that the startup program is okay now. Next, we can talk about Quartz scheduling task execution in detail.

Because we must not only perform one scheduling task, but also many scheduling tasks in the actual project operation, so we can change our thinking. Create a common startup center in the class library and refer to the NuGet package: Quartz. Then start creating a common core for scheduling tasks

private IScheduler scheduler;
    /// <summary>

    /// Create an entry for scheduling tasks

    /// </summary>

    /// <returns></returns>

    public async Task Start()
    {
      await StartJob();
    }

    /// <summary>
    /// Create a common call center for scheduling tasks
    /// </summary>
    /// <returns></returns>
    public async Task StartJob()
    {
      // Create a factory
      NameValueCollection param = new NameValueCollection()
      {
        { "testJob","test"}
      };

      StdSchedulerFactory factory = new StdSchedulerFactory(param);
      // Create a scheduler
      scheduler = await factory.GetScheduler();
      // Start scheduler
      await scheduler.Start();

      // Print an info log every three seconds
      await CreateJob<StartLogInfoJob>("_StartLogInfoJob", "_StartLogInfoJob", " 0/3 * * * * ? ");

      // Print a debug log every five seconds
      await CreateJob<StartLogDebugJob>("_StartLogDebugJob", "_StartLogDebugJob", " 0/5 * * * * ? ");

      // Scheduler time generation address -- http://cron.qe2.com

    }

    /// <summary>
    /// Stop Scheduler      
    /// </summary>
    public void Stop()
    {
      scheduler.Shutdown();
       scheduler=null;
    }

    /// <summary>
    /// Create a running scheduler
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="name"></param>
    /// <param name="group"></param>
    /// <param name="cronTime"></param>
    /// <returns></returns>
    public async Task CreateJob<T>(string name,string group, string cronTime) where T: IJob
    {
      // Create a job
      var job = JobBuilder.Create<T>()
        .WithIdentity("name" + name, "gtoup" + group)
        .Build();

      // Create a trigger
      var tigger = (ICronTrigger)TriggerBuilder.Create()
        .WithIdentity("name" + name, "group" + group)
        .StartNow()
        .WithCronSchedule(cronTime)
        .Build();

      // Put jobs and triggers in the scheduler
      await scheduler.ScheduleJob(job, tigger);
    }

Then you create two classes that execute business logic, StartLogInfoJob and StartLogDebugJob, respectively.

public class StartLogInfoJob:IJob
  {
    public async Task Execute(IJobExecutionContext context)
    {
      await Start();
    }
    public async Task Start()
    {
      LogHelp.Debug ("Schedule Print Debug");
    }
  }

 
public class StartLogDebugJob : IJob
  {
    public async Task Execute(IJobExecutionContext context)
    {
      await Start();
    }
    public async Task Start()
    {
      LogHelp. Info ("Scheduling Print Info");
    }
  }

At this point, we have successfully completed a scheduler to perform tasks. Finally, we have to rewrite the Program file. The program file generated by the console application does not meet our requirements, and the scheduler is started in it.


class Program
  {
    static void Main(string[] args)
    {
      HandleStart();
      var webHostArgs = args.Where(arg => arg != "--console").ToArray();
      var host = WebHost.CreateDefaultBuilder(webHostArgs)
        .UseStartup<Startup>()
        .UseKestrel(options => {
          options.Limits.MinRequestBodyDataRate = null;
        })
        .Build();
      host.Run();
    }
    static void HandleStart()
    {
      try
      {
        new Scheduler().Start().GetAwaiter().GetResult();
      }
      catch (Exception ex)
      {
        LogHelp.Error(ex);
      }
    }
  }

If we look at the Log file under the folder, we will find a Debug and an Info

At this point, our scheduling is completed, and when we need to use it, we can replace the print log with the business logic we want to deal with everyday. Just mention printing logs, by the way, how to print logs in. Net Core.

3. Net Cor Printing Log Files

Print the log file mainly using the NuGet package: NLog, and then add a NLog. config, first install the NLog package in the project, and then create a LogHelper public class.


public class LogHelp
  {
    static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();

    public static void Debug(string info)
    {
      logger.Debug(info);
    }

    public static void Info(string info)
    {
      logger.Info(info);
    }

    public static void Error(Exception ex, string info = "")
    {
      logger.Error(ex);
    }

}

Then add a NLog. config file


<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" autoReload="true">

 <targets>
  <target name="defaultlog" xsi:type="File" keepFileOpen="false" encoding="utf-8"
    fileName="${basedir}/logs/${level}/${shortdate}.log"
    layout="${longdate}|${level:uppercase=true}|${logger}|${message}" />
 </targets>

 <rules>
  <logger name="*" minlevel="trace" writeTo="defaultlog" />
 </rules>
</nlog>

By completing these two, you can print the log.

NET Core uses Quartz to carry out advanced and detailed integration of scheduling tasks. I hope it will be helpful to you. If you have any questions, please leave a message for me. NET Core will reply to you in time. Thank you very much for your support to developpaer.

Recommended Today

Implementation of PHP Facades

Example <?php class RealRoute{ public function get(){ Echo’Get me’; } } class Facade{ public static $resolvedInstance; public static $app; public static function __callStatic($method,$args){ $instance = static::getFacadeRoot(); if(!$instance){ throw new RuntimeException(‘A facade root has not been set.’); } return $instance->$method(…$args); } // Get the Facade root object public static function getFacadeRoot() { return static::resolveFacadeInstance(static::getFacadeAccessor()); } protected […]