วิธีกำหนดเวลางานโดยใช้ Quartz.NET ใน ASP.NET Core

เมื่อทำงานกับเว็บแอปพลิเคชันคุณมักจะต้องดำเนินการบางอย่างในพื้นหลัง ในบางกรณีสิ่งเหล่านี้จะเป็นงานที่ควรดำเนินการตามช่วงเวลาที่กำหนดไว้ล่วงหน้า

Quartz.NET เป็นพอร์ต. NET แบบโอเพ่นซอร์สของเฟรมเวิร์กการจัดกำหนดการงาน Java ยอดนิยม มีการใช้งานมาเป็นเวลานานและให้การสนับสนุนที่ดีเยี่ยมสำหรับการทำงานกับนิพจน์ Cron คุณสามารถเรียนรู้เพิ่มเติมเกี่ยวกับ Quartz.NET ได้จากโพสต์ก่อนหน้านี้ที่นี่ 

บทความนี้นำเสนอการอภิปรายเกี่ยวกับวิธีที่เราสามารถทำงานกับ Quartz.NET ใน ASP.NET Core เพื่อกำหนดเวลางานเบื้องหลัง

ในการทำงานกับตัวอย่างโค้ดที่ให้ไว้ในบทความนี้คุณควรติดตั้ง Visual Studio 2019 ในระบบของคุณ หากคุณยังไม่มีสำเนาคุณสามารถดาวน์โหลด Visual Studio 2019 ได้ที่นี่ 

สร้างโครงการ ASP.NET Core API

ก่อนอื่นมาสร้างโครงการ ASP.NET Core ใน Visual Studio สมมติว่ามีการติดตั้ง Visual Studio 2019 ในระบบของคุณให้ทำตามขั้นตอนที่ระบุด้านล่างเพื่อสร้างโครงการ ASP.NET Core ใหม่ใน Visual Studio

  1. เปิด Visual Studio IDE
  2. คลิกที่ "สร้างโครงการใหม่"
  3. ในหน้าต่าง“ สร้างโครงการใหม่” เลือก“ ASP.NET Core Web Application” จากรายการเทมเพลตที่แสดง
  4. คลิกถัดไป
  5. ในหน้าต่าง "กำหนดค่าโครงการใหม่ของคุณ" ที่แสดงถัดไประบุชื่อและที่ตั้งสำหรับโครงการใหม่
  6. คลิกสร้าง
  7. ในหน้าต่าง“ Create New ASP.NET Core Web Application” ให้เลือก. NET Core เป็นรันไทม์และ ASP.NET Core 2.2 (หรือใหม่กว่า) จากรายการดรอปดาวน์ที่ด้านบน ฉันจะใช้ ASP.NET Core 3.0 ที่นี่
  8. เลือก“ API” เป็นเทมเพลตโครงการเพื่อสร้างแอปพลิเคชัน ASP.NET Core API ใหม่ 
  9. ตรวจสอบให้แน่ใจว่าไม่มีการเลือกช่องทำเครื่องหมาย "เปิดใช้งานการสนับสนุน Docker" และ "กำหนดค่าสำหรับ HTTPS" เนื่องจากเราจะไม่ใช้คุณลักษณะเหล่านั้นที่นี่
  10. ตรวจสอบให้แน่ใจว่าการรับรองความถูกต้องถูกตั้งค่าเป็น“ ไม่มีการพิสูจน์ตัวตน” เนื่องจากเราจะไม่ใช้การพิสูจน์ตัวตน
  11. คลิกสร้าง 

สิ่งนี้จะสร้างโครงการ ASP.NET Core API ใหม่ใน Visual Studio เลือกโฟลเดอร์โซลูชัน Controllers ในหน้าต่าง Solution Explorer และคลิก“ Add -> Controller …” เพื่อสร้างคอนโทรลเลอร์ใหม่ชื่อ DefaultController

ถัดไปในการทำงานกับ Quartz คุณควรติดตั้งแพ็คเกจ Quartz จาก NuGet คุณสามารถทำได้ผ่านตัวจัดการแพ็คเกจ NuGet ภายใน Visual Studio 2019 IDE หรือโดยดำเนินการคำสั่งต่อไปนี้ที่คอนโซลตัวจัดการแพ็คเกจ NuGet:

ติดตั้ง - แพคเกจควอตซ์

งาน Quartz.NET ทริกเกอร์และตัวกำหนดตารางเวลา 

แนวคิดหลักสามประการใน Quartz.NET คืองานทริกเกอร์และตัวกำหนดตารางเวลา งานมีรหัสเพื่อดำเนินการงานหรืองานที่ต้องดำเนินการ งานแสดงโดยคลาสที่ใช้อินเทอร์เฟซ IJob ทริกเกอร์ใช้เพื่อระบุกำหนดการและรายละเอียดอื่น ๆ ของงาน คุณสามารถใช้ประโยชน์จากทริกเกอร์เพื่อระบุวิธีดำเนินการงาน ตัวกำหนดตารางเวลาเป็นส่วนประกอบที่รับผิดชอบในการสำรวจและดำเนินงานตามกำหนดการที่กำหนดไว้ล่วงหน้า

สร้างตัวกำหนดตารางเวลาโดยใช้ Quartz.NET

ควรสังเกตว่าคุณสามารถมีตัวกำหนดตารางเวลาได้หลายตัวในแอปพลิเคชัน อย่างไรก็ตามเราจะใช้ตัวกำหนดตารางเวลาเพียงตัวเดียวที่นี่เพื่อความเรียบง่าย ข้อมูลโค้ดต่อไปนี้แสดงให้เห็นว่าคุณสามารถสร้างอินสแตนซ์ตัวกำหนดตารางเวลาได้อย่างไร

ตัวกำหนดตารางเวลา var = StdSchedulerFactory.GetDefaultScheduler (). GetAwaiter (). GetResult ();

เมื่อสร้างตัวกำหนดตารางเวลาแล้วคุณสามารถใช้โค้ดต่อไปนี้ในเมธอด ConfigureServices ของไฟล์ Startup.cs เพื่อเพิ่มอินสแตนซ์ตัวกำหนดตารางเวลาเป็นบริการซิงเกิลตัน

services.AddSingleton (ตัวกำหนดตารางเวลา);

เริ่มและหยุดตัวกำหนดตารางเวลาโดยใช้ Quartz.NET

ในการเริ่มและหยุดตัวกำหนดตารางเวลาเราจะใช้ประโยชน์จากบริการโฮสติ้ง ในการดำเนินการนี้คุณต้องสร้างคลาสที่ใช้อินเทอร์เฟซ IHostingService ดังที่แสดงในข้อมูลโค้ดด้านล่าง

คลาสสาธารณะ CustomQuartzHostedService: IHostedService

{

        IScheduler _scheduler แบบอ่านอย่างเดียวส่วนตัว;

        CustomQuartzHostedService สาธารณะ (ตัวกำหนดตารางเวลา IScheduler)

        {

            _scheduler = ตัวกำหนดตารางเวลา;

        }

        Public async Task StartAsync (การยกเลิกโทเค็นการยกเลิกโทเคน)

        {

            รอ _scheduler? .Start (การยกเลิกโทเค็น);

        }

        งาน async สาธารณะ StopAsync (การยกเลิกโทเค็นการยกเลิกโทเค็น)

        {

            รอ _scheduler?. ปิด (การยกเลิกโทเค็น);

        }

 }

โปรดทราบว่าคุณควรลงทะเบียนบริการที่โฮสต์ในคอลเล็กชันบริการในวิธี ConfigureServices โดยใช้ข้อมูลโค้ดที่ระบุด้านล่าง

บริการ AddHostedService ();

นี่คือวิธี ConfigureServices ที่อัปเดตสำหรับการอ้างอิงของคุณ:

โมฆะสาธารณะ ConfigureServices (บริการ IServiceCollection)

{

    services.AddControllers ();

    ตัวกำหนดตารางเวลา var =

    StdSchedulerFactory.GetDefaultScheduler (). GetAwaiter (). GetResult ();

    services.AddSingleton (ตัวกำหนดตารางเวลา);

    บริการ AddHostedService ();

}

สร้างงานโดยใช้ Quartz.NET

ดังที่ได้กล่าวไปแล้วงานคือคลาสที่ใช้อินเทอร์เฟซ IJob และมีเมธอด Execute () เมธอด Execute () ยอมรับอินสแตนซ์ประเภท IJobExecutionContext

ข้อมูลโค้ดต่อไปนี้แสดงคลาสงานที่มีเมธอด asynchronous Execute () ด้วย วิธีนี้มีรหัสที่สอดคล้องกับงานที่งานของคุณควรทำ

[DisallowConcurrentExecution]

การแจ้งเตือนระดับสาธารณะ: IJob

    {

        ILogger _logger แบบอ่านอย่างเดียวส่วนตัว

        NotificationJob สาธารณะ (ILogger logger)

        {

            _logger = คนตัดไม้;

        }

        Public Task Execute (บริบท IJobExecutionContext)

        {

            _logger.LogInformation ("สวัสดีชาวโลก - - ');

            ส่งคืน Task.CompletedTask;

        }

    }

สร้างโรงงานงานโดยใช้ Quartz.NET

โรงงานงานคือคลาสที่สืบทอดอินเทอร์เฟซ IJobFactory และใช้เมธอด NewJob () และ ReturnJob () สามารถใช้ข้อมูลโค้ดต่อไปนี้เพื่อสร้างคลาสโรงงานที่สามารถสร้างและส่งคืนอินสแตนซ์งาน

CustomQuartzJobFactory คลาสสาธารณะ: IJobFactory

    {

        ส่วนตัวอ่านอย่างเดียว IServiceProvider _serviceProvider;

        CustomQuartzJobFactory สาธารณะ (IServiceProvider serviceProvider)

        {

            _serviceProvider = serviceProvider;

        }

        IJob NewJob สาธารณะ (TriggerFiredBundle triggerFiredBundle,

        ตัวกำหนดตารางเวลา IScheduler)

        {

            var jobDetail = triggerFiredBundle.JobDetail;

            ส่งคืน (IJob) _serviceProvider.GetService (jobDetail.JobType);

        }

        โมฆะสาธารณะ ReturnJob (งาน IJob) {}

    }

โปรดทราบว่าการใช้งานนี้ไม่ได้ใช้ประโยชน์จากการรวมงาน หากคุณต้องการใช้การรวมงานคุณควรเปลี่ยนเมธอด NewJob () แล้วใช้เมธอด ReturnJob ()

สร้างคลาส JobMetadata เพื่อจัดเก็บข้อมูลเมตาของงานของคุณ

เราจะใช้คลาสที่กำหนดเองเพื่อจัดเก็บข้อมูลเมตาที่เกี่ยวข้องกับงานเช่นรหัสงานชื่อ ฯลฯ คลาสต่อไปนี้แสดงถึงคลาสข้อมูลเมตาของงาน

JobMetadata ระดับสาธารณะ

    {

        Guid JobId สาธารณะ {รับ; ชุด; }

        ประเภทสาธารณะ JobType {get; }

        สตริงสาธารณะ JobName {get; }

        สตริงสาธารณะ CronExpression {get; }

        JobMetadata สาธารณะ (Guid Id, พิมพ์ jobType, string jobName,

        สตริง cronExpression)

        {

            JobId = Id;

            JobType = jobType;

            JobName = jobName;

            CronExpression = cronExpression;

        }

    }

สร้างบริการที่โฮสต์เพื่อเริ่มและหยุดตัวกำหนดตารางเวลา Quartz.NET

ต่อไปเราจะต้องติดตั้งบริการโฮสต์ บริการที่โฮสต์คือคลาสที่ใช้อินเทอร์เฟซ IHostedService และเริ่มตัวกำหนดตารางเวลา Quartz รายการรหัสต่อไปนี้แสดงคลาสบริการที่โฮสต์แบบกำหนดเอง

คลาสสาธารณะ CustomQuartzHostedService: IHostedService

    {

        ส่วนตัวแบบอ่านอย่างเดียว ISchedulerFactory SchedulerFactory;

        IJobFactory jobFactory แบบอ่านอย่างเดียวส่วนตัว;

        JobMetadata แบบอ่านอย่างเดียวส่วนตัว

        CustomQuartzHostedService สาธารณะ (ISchedulerFactory

            โรงงาน,

            JobMetadata jobMetadata,

            IJobFactory jobFactory)

        {

            this.schedulerFactory = SchedulerFactory;

            this.jobMetadata = jobMetadata;

            this.jobFactory = jobFactory;

        }

        IScheduler Scheduler สาธารณะ {รับ; ชุด; }

        Public async Task StartAsync (การยกเลิกโทเค็นการยกเลิกโทเคน)

        {

            Scheduler = รอตัวกำหนดตารางเวลาโรงงาน GetScheduler ();

            Scheduler.JobFactory = jobFactory;

            var job = CreateJob (jobMetadata);

            var trigger = CreateTrigger (jobMetadata);

            รอตัวจัดกำหนดการตารางงาน (งานทริกเกอร์การยกเลิกโทเค็น);

            รอตัวกำหนดเวลาเริ่มต้น (การยกเลิกโทเค็น);

        }

        งาน async สาธารณะ StopAsync (การยกเลิกโทเค็นการยกเลิกโทเค็น)

        {

            รอตัวกำหนดเวลาหรือไม่. ปิด (การยกเลิกโทเค็น);

        }

        ITrigger ส่วนตัว CreateTrigger (JobMetadata jobMetadata)

        {

            ส่งคืน TriggerBuilder.Create ()

            .WithIdentity (jobMetadata.JobId ToString ())

            .WithCronSchedule (jobMetadata.CronExpression)

            .WithDescription ($ "{jobMetadata.JobName}")

            .สร้าง();

        }

        IJobDetail ส่วนตัว CreateJob (JobMetadata jobMetadata)

        {

            ส่งคืน JobBuilder

            .Create (jobMetadata.JobType)

            .WithIdentity (jobMetadata.JobId ToString ())

            .WithDescription ($ "{jobMetadata.JobName}")

            .สร้าง();

        }

    }

ข้อมูลโค้ดต่อไปนี้แสดงโค้ดทั้งหมดของเมธอด ConfigureServices ของคลาส Startup

โมฆะสาธารณะ ConfigureServices (บริการ IServiceCollection)

{

services.AddControllers ();

บริการ. AddSingleton ();

บริการ. AddSingleton ();

บริการ. AddSingleton ();

services.AddSingleton (JobMetadata ใหม่ (Guid.NewGuid (), typeof (NotificationJob), "Notification Job", "0/10 * * * *?"));

บริการ AddHostedService ();

}

และนั่นคือทั้งหมดที่คุณต้องทำ! เมื่อคุณเรียกใช้แอปพลิเคชันคุณจะสังเกตเห็นว่าเมธอด Execute () ของคลาส NotificationJob ทำงานทุกๆ 10 วินาที

Quartz.NET เป็นทางเลือกที่ดีสำหรับการใช้งานตัวกำหนดตารางเวลาในแอปพลิเคชันของคุณ คุณสามารถใช้ประโยชน์จากคุณสมบัติการคงอยู่ใน Quartz.NET เพื่อจัดเก็บงานของคุณในฐานข้อมูลเช่น SQL Server, PostgreSQL หรือ SQLite ได้เช่นกัน