TEMEL
Fire-and-Forget Jobs
Fire-and-forget job'lar hemen (veya ilk fırsatta) çalıştırılan tek seferlik görevlerdir. En yaygın Hangfire kullanım senaryosudur.
Karar Rehberi
| Durum | Öneri | Örnek veya gerekçe |
|---|---|---|
| E-posta/SMS gönderimi | Uygun | Sipariş onay e-postası |
| Webhook tetikleme | Uygun | Payment gateway callback |
| Thumbnail oluşturma | Uygun | Kullanıcı profil fotoğrafı resize |
| Senkron sonuç beklenen iş | Uygun değil: await kullan | API response'da sonuç lazım |
| 50ms altı latency gereken | Uygun değil: doğrudan çağır | Cache lookup |
Temel Kullanım
// En basit form — static method
BackgroundJob.Enqueue(() => Console.WriteLine("Merhaba Hangfire!"));
// Servis injection ile (önerilen)
BackgroundJob.Enqueue<IEmailService>(service =>
service.SendOrderConfirmation(orderId));
// Queue belirterek
BackgroundJob.Enqueue<IEmailService>(
service => service.SendOrderConfirmation(orderId),
"critical");DI-Friendly Pattern (Önerilen)
public interface IOrderNotificationService
{
Task SendConfirmationAsync(int orderId);
}
public class OrderNotificationService : IOrderNotificationService
{
private readonly IEmailSender _emailSender;
private readonly IOrderRepository _orderRepo;
public OrderNotificationService(IEmailSender emailSender, IOrderRepository orderRepo)
{
_emailSender = emailSender;
_orderRepo = orderRepo;
}
public async Task SendConfirmationAsync(int orderId)
{
var order = await _orderRepo.GetByIdAsync(orderId);
if (order is null) return;
await _emailSender.SendAsync(
to: order.CustomerEmail,
subject: "Siparişiniz onaylandı",
body: GenerateEmailBody(order));
}
}
// Controller'da kullanım
[HttpPost("orders")]
public IActionResult CreateOrder([FromBody] CreateOrderRequest request)
{
var orderId = _orderService.Create(request);
// Background'da çalışacak — response hemen döner
BackgroundJob.Enqueue<IOrderNotificationService>(
svc => svc.SendConfirmationAsync(orderId));
return CreatedAtAction(nameof(GetOrder), new { id = orderId }, null);
}Argüman kuralı: Job argümanları JSON olarak serialize edilir. Entity nesnesi değil, ID geçin. Büyük nesneler storage'ı şişirir ve deserialization sorunlarına yol açar.
// Tüm entity job storage'a yazılır — MB'larca veri + deserialization riski
BackgroundJob.Enqueue<IReportService>(svc => svc.Generate(complexReportObject));// Hafif, güvenli — job içinde DB'den taze veriyi çeker
BackgroundJob.Enqueue<IReportService>(svc => svc.Generate(reportId));Örnek: Bir SaaS platformunda kullanıcı dosya yükleyince, API hemen 202 Accepted döner. Arka planda fire-and-forget job dosyayı işler (virus scan → resize → S3 upload → DB güncelle). Kullanıcı polling ile durumu kontrol eder.