در دنیای توسعه وب، بسیاری از پروژهها نیازمند اجرای وظایف پسزمینهای هستند که باید بدون ایجاد وقفه برای کاربر انجام شوند. وظایف زمانبندیشده «Scheduled Tasks» مانند ارسال ایمیلهای دورهای، جمعآوری دادهها و گزارشگیری نمونههایی از این وظایف هستند. در ASP.NET Core، کتابخانه Hangfire یک راهحل قدرتمند و آسان برای مدیریت و اجرای این وظایف ارائه میدهد. این مقاله ابتدا به معرفی Hangfire و قابلیتهای آن میپردازد، سپس به پیادهسازی یک پروژه عملی با استفاده از Hangfire در ASP.NET Core برای مدیریت وظایف زمانبندیشده میپردازد.
مقدمه
در برنامههای مدرن تحت وب، وظایف پسزمینه نقش مهمی در پردازش اطلاعات، مدیریت دادهها، و انجام کارهای تکراری و زمانبندیشده ایفا میکنند. یکی از چالشهای اصلی در پیادهسازی وظایف پسزمینه، مدیریت زمانبندی، پردازش موازی، و نگهداری از نتایج پردازش است. Hangfire یک کتابخانه اپنسورس و قدرتمند در ASP.NET Core است که امکان مدیریت و اجرای وظایف زمانبندیشده و پردازشهای پسزمینهای را بدون نیاز به تغییرات گسترده در ساختار برنامه فراهم میکند. این ابزار با پشتیبانی از دیتابیسهای مختلف و رابط کاربری برای مانیتورینگ، پیادهسازی و مدیریت وظایف را ساده و کارآمد کرده است.
آشنایی با Hangfire
Hangfire یک فریمورک است که برای اجرای وظایف پسزمینهای در .NET طراحی شده است. از ویژگیهای مهم Hangfire میتوان به موارد زیر اشاره کرد:
- انواع وظایف پسزمینه: اجرای وظایف بهصورت همزمان، تأخیری، تکراری و زمانبندیشده
- پشتیبانی از دیتابیسهای مختلف: پشتیبانی از SQL Server، PostgreSQL، MySQL و Redis
- مانیتورینگ: رابط کاربری تحت وب برای مشاهده و مدیریت وضعیت وظایف
- پایداری و بازیابی خطا: وظایف با خطا دوباره اجرا شده و تاریخچهی اجرای وظایف قابل مشاهده است.
Hangfire با استفاده از ASP.NET Core، نیاز به ایجاد ساختار جدیدی برای مدیریت وظایف پسزمینه ندارد و بهراحتی میتوان آن را به یک پروژهی موجود اضافه کرد.
نصب و پیکربندی Hangfire در ASP.NET Core
برای شروع استفاده از Hangfire، ابتدا باید کتابخانه آن را به پروژه ASP.NET Core خود اضافه کنید. این کار از طریق مدیر بستههای NuGet امکانپذیر است.
Install-Package Hangfire Install-Package Hangfire.AspNetCore
پیکربندی Hangfire
پس از نصب، Hangfire را باید در برنامه تنظیم کنید. برای این کار، به فایل Startup.cs
بروید و Hangfire را به سرویسهای برنامه اضافه کنید.
using Hangfire; using Hangfire.SqlServer; public class Startup { public void ConfigureServices(IServiceCollection services) { // تنظیمات مربوط به Hangfire با استفاده از SQL Server services.AddHangfire(config => config.SetDataCompatibilityLevel(CompatibilityLevel.Version_170) .UseSimpleAssemblyNameTypeSerializer() .UseDefaultTypeSerializer() .UseSqlServerStorage("YourConnectionString", new SqlServerStorageOptions { CommandBatchMaxTimeout = TimeSpan.FromMinutes(5), SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5), QueuePollInterval = TimeSpan.Zero, UseRecommendedIsolationLevel = true, DisableGlobalLocks = true })); // اضافه کردن Hangfire به سرویسها services.AddHangfireServer(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // راهاندازی Hangfire app.UseHangfireDashboard(); } }
در کد بالا، Hangfire به سرور SQL Server متصل شده است، اما شما میتوانید از دیتابیسهای دیگر مانند PostgreSQL یا Redis نیز استفاده کنید.
انواع وظایف در Hangfire
در Hangfire چهار نوع وظیفهی اصلی وجود دارد که هر کدام برای سناریوهای خاصی مناسب هستند:
- Fire-and-Forget Jobs: وظایفی که بلافاصله و تنها یک بار اجرا میشوند.
- Delayed Jobs: وظایفی که پس از یک بازه زمانی مشخص اجرا میشوند.
- Recurring Jobs: وظایفی که به صورت تکراری در زمانهای معین اجرا میشوند.
- Continuations: وظایفی که پس از اتمام یک وظیفه دیگر اجرا میشوند.
تعریف هر یک از وظایف در Hangfire
در ادامه استفاده از Hangfire برای مدیریت وظایف زمانبندیشده در ASP.NET Core چهار وظیفه اصلی توضیح و تشریح میشوند.
۱- Fire-and-Forget Job
این نوع وظیفه بلافاصله پس از فراخوانی اجرا میشود و معمولا برای کارهای کوتاه و سریع استفاده میشود.
public void RegisterJobs() { BackgroundJob.Enqueue(() => Console.WriteLine("This is a fire-and-forget job!")); }
۲- Delayed Job
وظایفی که پس از گذشت زمانی مشخص اجرا میشوند. برای مثال، ارسال یک ایمیل یادآوری پس از ۲۴ ساعت.
public void ScheduleEmailReminder() { BackgroundJob.Schedule(() => Console.WriteLine("Email reminder sent!"), TimeSpan.FromHours(24)); }
۳- Recurring Job
وظایفی که به صورت مداوم و زمانبندیشده اجرا میشوند. برای مثال، یک گزارش روزانه در ساعت ۱۲ شب تولید شود.
public void ConfigureRecurringJobs() { RecurringJob.AddOrUpdate("generate-daily-report", () => Console.WriteLine("Generating daily report..."), Cron.Daily); }
۴- Continuation Job
وظایفی که پس از اتمام یک وظیفه دیگر اجرا میشوند. برای مثال، پس از ارسال ایمیل، یک پیام تایید در کنسول نمایش داده شود.
public void ConfigureContinuationJob() { var jobId = BackgroundJob.Enqueue(() => Console.WriteLine("Sending email...")); BackgroundJob.ContinueWith(jobId, () => Console.WriteLine("Email sent!")); }
پیادهسازی یک پروژه عملی
در این بخش، یک پروژه عملی را پیادهسازی میکنیم که شامل ارسال ایمیلهای اطلاعرسانی به کاربران به صورت زمانبندیشده است.
مرحله ۱: ایجاد سرویس ارسال ایمیل
ابتدا یک سرویس برای ارسال ایمیل تعریف میکنیم. این سرویس شامل متدهای مورد نیاز برای ارسال ایمیل به کاربران است.
public interface IEmailService { void SendEmail(string to, string subject, string body); } public class EmailService : IEmailService { public void SendEmail(string to, string subject, string body) { // کد ارسال ایمیل Console.WriteLine($"Email sent to {to} with subject {subject}"); } }
مرحله ۲: افزودن سرویس به DI و تنظیم Hangfire
سرویس ارسال ایمیل را به DI اضافه کرده و یک وظیفهی زمانبندیشده برای ارسال ایمیلها تنظیم میکنیم.
public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddScoped<IEmailService, EmailService>(); // تنظیم Hangfire services.AddHangfire(...); services.AddHangfireServer(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseHangfireDashboard(); } }
مرحله ۳: ایجاد وظیفه ارسال ایمیل با Hangfire
برای اجرای وظیفه ارسال ایمیل بهصورت زمانبندیشده، یک Recurring Job تنظیم میکنیم تا ایمیلها را هر روز ساعت ۹ صبح ارسال کند.
public class NotificationJob { private readonly IEmailService _emailService; public NotificationJob(IEmailService emailService) { _emailService = emailService; } public void SendDailyNotifications() { _emailService.SendEmail("user@example.com", "Daily Notification", "This is your daily notification."); } }
در فایل Startup.cs
، تنظیمات مربوط به وظیفهی روزانه را انجام میدهیم: