مجدول المهام في C# (.NET): من المؤقت البسيط إلى Quartz.NET الصناعي
مجدول المهام (Task Scheduler) هو جزء لا يتجزأ من أي تطبيق جاد. سواء كان تنظيفًا دوريًا للذاكرة المؤقتة، أو إرسال رسائل البريد الإلكتروني الجماعية، أو مزامنة البيانات مع API خارجي - لا يمكن الاستغناء عن آلية موثوقة لتنفيذ العمليات الخلفية. في نظام .NET البيئي، يتوفر للمطور عدة طرق: من المؤقت المدمج System.Threading.Timer إلى إطار العمل القوي والمرن Quartz.NET. في هذه المقالة، سنقوم بتحليل كلا الخيارين، وسنعرض أمثلة على الكود، ونساعدك في اختيار الأداة المناسبة لمشروعك.
1. المؤقت المدمج System.Threading.Timer
أبسط وأخف طريقة لتشغيل مهمة وفقًا لجدول زمني هي استخدام System.Threading.Timer. لا يتطلب تثبيت حزم خارجية وهو مثالي للسيناريوهات البسيطة: تنفيذ طريقة على فترات زمنية ثابتة أو تأخير لمرة واحدة.
مثال: تنفيذ مهمة كل 5 ثوانٍ
using System;using System.Threading;
class Program{ static void Main() { // إنشاء مؤقت يقوم بتشغيل رد الاتصال كل 5 ثوانٍ Timer timer = new Timer(DoWork, null, TimeSpan.Zero, TimeSpan.FromSeconds(5)); Console.WriteLine("تم تشغيل المؤقت. اضغط على Enter للخروج."); Console.ReadLine(); timer.Dispose(); }
static void DoWork(object state) { Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] تنفيذ مهمة خلفية..."); }}المزايا:
- مدمج في .NET، لا حاجة لمكتبات إضافية.
- استهلاك ضئيل للموارد.
- سهولة الاستخدام.
العيوب:
- لا يوجد دعم مدمج لتعبيرات CRON.
- صعوبة إدارة مهام متعددة بجداول زمنية مختلفة.
- لا توجد آليات للاستمرارية (تُفقد المهام عند إعادة التشغيل).
- يتم تنفيذ رد الاتصال في خيط من التجمع، وقد تحدث مشاكل في المزامنة.
للمشاريع التعليمية والأدوات البسيطة، يعتبر System.Threading.Timer خيارًا ممتازًا. ومع ذلك، بالنسبة لتطبيقات الإنتاج التي تحتوي على عشرات المهام، يجب النظر في حلول أكثر تقدمًا.
2. Quartz.NET - مجدول المهام الصناعي
Quartz.NET هو إطار عمل قوي ومرن وناضج لجدولة المهام في .NET. مستوحى من نظيره الشهير في Java Quartz ويدعم:
- تعبيرات CRON لجدولة مرنة (كل ساعتين، أيام الأسبوع في الساعة 9:00 صباحًا، إلخ).
- استمرارية المهام (الحفظ في قاعدة البيانات).
- التجميع (يمكن لعدة خوادم تنفيذ المهام).
- معالجة المهام الفائتة (misfire handling).
- المهام الفرعية والمشغلات.
تثبيت Quartz.NET
قم بتثبيت الحزمة عبر NuGet:
dotnet add package Quartzمثال: مهمة بسيطة بجدول CRON
using System;using System.Threading.Tasks;using Quartz;using Quartz.Impl;
class Program{ static async Task Main() { // إنشاء المجدول StdSchedulerFactory factory = new StdSchedulerFactory(); IScheduler scheduler = await factory.GetScheduler(); await scheduler.Start();
// تعريف المهمة (Job) IJobDetail job = JobBuilder.Create<HelloJob>() .WithIdentity("helloJob", "group1") .Build();
// إنشاء مشغل: كل يوم في الساعة 10:30 صباحًا ITrigger trigger = TriggerBuilder.Create() .WithIdentity("trigger1", "group1") .WithCronSchedule("0 30 10 ? * * *") // CRON: ثانية، دقيقة، ساعة، يوم، شهر، يوم الأسبوع .Build();
// تسجيل المهمة مع المشغل await scheduler.ScheduleJob(job, trigger);
Console