پیاده سازی background task  با استفاده از Hangfire در NET 7.

قبل از اینکه برویم سراغ استفاده از Hangfire بیاید تعریفی از background job ها داشته باشیم، این نوع Job ها برای در صف قرار دادن برخی فرایندها مورد استفاده قرار میگیرند که در پس زمینه اجرا می شوند.به عنوان مثال اجرای task های طولانی مدت بدون اینکه کاربر نهایی منتظر اتمام آن باشد، یا دریافت یک گزارش از برنامه که برای تولید این گزارش زمان زیادی نیاز داشته باشیم.تعریف Hangfireیکی از پکیج های open-source که میتوان استفاده کرد Hangfire میباشد. این پکیچ به‌صورت چند نخی (multi-thread) است و به سادگی قابل ارتقا می باشد، همچنین به دلیل ساختار خوبی که دارد به شما عملکرد بسیار قدرتمندی ارائه می دهد.دلایل استفاده از Hangfireبه‌صورت کلی برای انجام task های پس زمینه مانند ارسال ایمیل، import کردن فایل ها، ویدیوها، نگهداری پایگاه داده و ... را در اختیار شما قرار می دهد.داشبورد و پایگاه داده Hangfire از طریق داشبورد Hangfire میتوانیم تمامی job های در حال اجرا یا زمانبندی شده را که توسط hangfire client ایجاد شده است را مشاهده کنیم، همچنین این در داشبورد میتوانید تمامی خطاها، job هایی که باید دوباره اجرا شوند، و آنهایی که در صف اجرا هستند را مشاهده کرد.یکی دیگر از مزایای استفاده از این داشبورد اجرای دستی job ها هستند.انواع تایپهای job ها در Hangfireدر حال حاضر 6 نوع تایپ برای اجرای Job ها در hangfire وجود دارند:جاب Fire-and-Forgetاین نوع job ها فقط یکبار بعد از ایجاد اجرا میشوند و سپس از چرخه ی اجرا برای همیشه خارج میشوند.جاب Delayedاین نوع job ها تنها یکبار اجرا می شوند، اما نه بعد از ایجاد آن، بلکه در یک دوره زمانی مشخص.جاب Recurringاین نوع job چندین بار در طول زمانی متفاوت اجرا می شوند، به عنوان مثال روزی یکبار، یا هر ساعت و...جاب Continuationsاین نوع job زمانی اجرا میشوند که جاب پدر (parent job) به اتمام رسیده باشد.همچنین دو نوع دیگر job ها وجود دارند اما در نسخه open-source ارائه نمی شوند و نیاز به تهیه لایسنس مربوط به آن هستین، این دو نوع Batches و Batch Continuations هستند.جاب Batches این نوع جاب همانطور که از نام آن پیداست، گروهی از جاب ها را شامل میشوند که به به‌صورت خودکار قابل اجرا هستند.جاب Batch Continuationsاین نوع جاب زمانی اجرا میشوند که جاب پدر (parent job) به اتمام رسیده باشد.توسعه Hangfire در ASP.NET Coreقدم 1بعد از تعاریف Hangfire نوبت آن است که آن را پیاده‌سازی کنیم، برای این منظور نیاز به ایجاد یک پروژه ASP.NET Core Web API داریم.بدین منظور در Visual Studio 2022 یک پروژه ایجاد میکنیم.قدم 2نام پروژه را به همراه مقصد آن مشخص میکنیم.قدم 3فریم ورک و همچنین نوع اجرا شدن آن را مشخص میکنیم، در اینجا فریم ورک را NET 7. انتخاب میکنیم.قدم 4بعد از ایجاد پروژه اقدام به نصب پکیج های مربوط به Hangfire میکنیم.Hangfire.AspNetCore Hangfire.SqlServer Microsoft.Data.SqlClientقدم 5حال نیاز داریم که تایپهای مختلفی که در بالا اشاره کردم را در یک کنترلر پیاده‌سازی کنیم.using Microsoft.AspNetCore.Mvc; namespace HangfireDemo.Controllers; [ApiController] public class HomeController : Controller { }جاب FireAndForget[HttpGet] [Route(&quotFireAndForgetJob&quot)] public string FireAndForgetJob() { var jobId = BackgroundJob.Enqueue(() => Console.WriteLine(&quotHello world - Fire and Forget Job&quot)); return $&quotJob ID: {jobId}, Hello world - Fire and Forget Job&quot }برای تعریف FireAndForgetJob باید از متد Enqueue استفاده کنیم سپس بعد از ایجاد جاب، بلافاصله اجرا خواهد شد.جاب Delayed[HttpGet] [Route(&quotDelayedJob&quot)] public string DelayedJob() { var jobId = BackgroundJob.Schedule(() => Console.WriteLine(&quotHello world - Delayed Job&quot), TimeSpan.FromSeconds(30)); return $&quotJob ID: {jobId}, Hello world - Delayed Job&quot }برای تعریف DelayedJobباید از متد Schedule استفاده کنیم سپس بعد از ایجاد جاب،در بازه زمانی مشخص اجرا خواهد شد، در این مثال 30 ثانیه پس از ایجاد Job آن اجرا خواهد شد. جاب Continuous[HttpGet] [Route(&quotContinuousJob&quot)] public string ContinuousJob() { var parentJobId = BackgroundJob.Enqueue(() => Console.WriteLine(&quotHello world - Fire and Forget Job&quot)); BackgroundJob .ContinueJobWith(parentJobId, () => Console.WriteLine(&quotHello world - continuous Job&quot)); return &quotWelcome user in continuous Job Demo!&quot }در این نوع جاب ابتدا از طریق متد Enqueue یک جاب را ایجاد کردیم، سپس پس از اجرا شدن آن از طریق متد ContinueJobWith، با شناسه مربوط به جاب پدر جاب فرزند را اجرا میکنیم.جاب Recurring[HttpGet] [Route(&quotRecurringJob&quot)] public string RecurringJobs() { RecurringJob .AddOrUpdate(() => Console.WriteLine(&quotHello world - Recurring Job&quot), Cron.Weekly); return &quotHello world - Recurring Job &quot }این جاب به‌صورت دوره ای اجرا خواهد شد، بدین منظور از متد AddOrUpdate استفاده میکنیم، به عنوان مثال این جاب به‌صورت هفتگی اجرا خواهد شد.قدم 6در این قدم تنظیمات مربوط به پایگاه داده را در appsettings.json پیکربندی میکنیم.{ &quotLogging&quot: { &quotLogLevel&quot: { &quotDefault&quot: &quotInformation&quot, &quotMicrosoft.AspNetCore&quot: &quotWarning&quot } }, &quotAllowedHosts&quot: &quot*&quot, &quotConnectionStrings&quot: { &quotHangfireConnection&quot: &quotServer=localhost;Database=dashboard;Integrated Security=true;MultipleActiveResultSets=true;TrustServerCertificate=Yes;&quot } }قدم 7حال نوبت به آن رسیده که پیکربندی Hangfire را در pipeline و middleware خود انجام دهیم، بدین منظور باید پیکربندی مربوط به پایگاه داده، ثبت کردن سرویس hangfire و همچنین پیکربندی UI را انجام دهیم.builder.Services.AddHangfire(x => { x.UseSqlServerStorage(builder.Configuration[&quotConnectionStrings:HangfireConnection&quot]); x.UseSimpleAssemblyNameTypeSerializer(); x.UseRecommendedSerializerSettings(); });در کد بالا تنظیمات مربوط به پایگاه داده را پیکربندی کردیم.builder.Services.AddHangfireServer();حال سرویس مربوط به سرور hangfire را ثبت میکنیم، این سرویس به صورت Transient ثبت خواهد شد.و در نهایت برای دسترسی به داشبورد و فراهم کردن UI از کد زیر استفاده میکنیم.app.UseHangfireDashboard(&quot/dashboard&quot);فایل program.cs در نهایت شبیه به زیر خواهد بود.using Hangfire; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllers(); builder.Services.AddHangfire(x => { x.UseSqlServerStorage(builder.Configuration[&quotConnectionStrings:HangfireConnection&quot]); x.UseSimpleAssemblyNameTypeSerializer(); x.UseRecommendedSerializerSettings(); }); builder.Services.AddHangfireServer(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.UseHangfireDashboard(&quot/dashboard&quot); app.Run();قدم 8قبل از اجرای برنامه اجازه دهید تا فایل launchSetting.json را به صورا زید بروز رسانی کنیم تا برنامه ما در پورت 5001 اجرا شود.&quothttps&quot: { &quotcommandName&quot: &quotProject&quot, &quotdotnetRunMessages&quot: true, &quotlaunchBrowser&quot: true, &quotlaunchUrl&quot: &quotswagger&quot, &quotapplicationUrl&quot: &quothttps://localhost:5001;http://localhost:5000&quot, &quotenvironmentVariables&quot: { &quotASPNETCORE_ENVIRONMENT&quot: &quotDevelopment&quot } },قدم 9زمان آن فرارسیده است تا برنامه خود را اجرا کنیم.بعد از اجرای برنامه، پنجره swagger باز خواهد شد و شما تمامی endpoint های API خود را در آن مشاهد خواهید کرد.همچنین جداول پایگاه داده ایجاد شده نیز به شکل زیر خواهند بود.قدم 10حال زمان آن رسیده است تا endpoint های API خود را اجرا کنیم، برای این منظور در صفحه Swagger تمامی endpoint ها را یک به یک اجرا میکنیم و سپس به داشبورد hangfire مراجعه میکنیم.داشبورد تمامی جاب های در حال اجرا یا زمانبندی شده را نمایش می دهد، همنچنین می توانیم اجرای جاب ها، خطاهای موجود در جاب ها و همچنین جابهای زمانبندی شده را نیز در این داشبورد مشاهده کنیم.خلاصهدر این مقاله نگاهی کردیم به پیاده‌سازی Hangfire در NET 7. و همچنین نحوه ایجاد background job ها.مشاهده ویدیو این مقالهاز کد نویسی لذت ببرید!