IHostedService & BackgroundService
Implementasikan IHostedService dan BackgroundService abstrak untuk menjalankan pekerjaan di latar belakang dalam host .NET.
IHostedService & BackgroundService adalah pelajaran C# Academy gratis di CoddyKit. Ini adalah pelajaran 1 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar C# Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus C# Academy mencakup 4 pelajaran total.
Apa Itu Layanan Latar Belakang?
Layanan latar belakang menjalankan pekerjaan jangka panjang bersama aplikasi ASP.NET Core Anda — memproses antrean, menjalankan tugas terjadwal, atau memantau sumber daya. .NET menyediakan dua antarmuka: IHostedService (minimal) dan BackgroundService abstrak (cocok untuk perulangan).
Antarmuka IHostedService
IHostedService memiliki dua metode: StartAsync (dipanggil saat host dimulai) dan StopAsync (dipanggil selama penghentian secara bertahap). Antarmuka ini ideal untuk tugas mulai dan berhenti sekali jalan.
public class DatabaseMigratorService : IHostedService
{
private readonly IServiceScopeFactory _scopeFactory;
public DatabaseMigratorService(IServiceScopeFactory sf) => _scopeFactory = sf;
public async Task StartAsync(CancellationToken ct)
{
using var scope = _scopeFactory.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
await db.Database.MigrateAsync(ct);
}
public Task StopAsync(CancellationToken ct) => Task.CompletedTask;
}
builder.Services.AddHostedService<DatabaseMigratorService>();BackgroundService: Perulangan Jangka Panjang
BackgroundService adalah kelas abstrak yang mengimplementasikan IHostedService dan menyediakan ExecuteAsync(CancellationToken) — metode yang berjalan selama siklus hidup aplikasi.
public class HeartbeatService : BackgroundService
{
private readonly ILogger<HeartbeatService> _logger;
public HeartbeatService(ILogger<HeartbeatService> l) => _logger = l;
protected override async Task ExecuteAsync(CancellationToken ct)
{
_logger.LogInformation("Heartbeat service started");
while (!ct.IsCancellationRequested)
{
_logger.LogInformation("Heartbeat: {Time}", DateTime.UtcNow);
await Task.Delay(TimeSpan.FromSeconds(30), ct);
}
_logger.LogInformation("Heartbeat service stopping");
}
}
builder.Services.AddHostedService<HeartbeatService>();Menggunakan Layanan dengan Cakupan
Layanan latar belakang bersifat Singleton. Untuk menggunakan layanan dengan cakupan (seperti DbContext), selalu buat cakupan baru untuk setiap unit pekerjaan menggunakan IServiceScopeFactory.
public class DataSyncService : BackgroundService
{
private readonly IServiceScopeFactory _factory;
private readonly ILogger<DataSyncService> _log;
public DataSyncService(IServiceScopeFactory f, ILogger<DataSyncService> l)
{ _factory = f; _log = l; }
protected override async Task ExecuteAsync(CancellationToken ct)
{
while (!ct.IsCancellationRequested)
{
using (var scope = _factory.CreateScope())
{
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
await SyncDataAsync(db, ct);
} // scope and DbContext disposed here
await Task.Delay(TimeSpan.FromMinutes(5), ct);
}
}
}Penghentian Secara Bertahap
Saat host dihentikan, host akan memicu token pembatalan. ExecuteAsync Anda harus memantau token tersebut dan melakukan pembersihan. Secara bawaan, host menunggu hingga 5 detik sebelum menghentikan proses secara paksa.
protected override async Task ExecuteAsync(CancellationToken ct)
{
try
{
while (!ct.IsCancellationRequested)
{
await DoWorkAsync(ct);
await Task.Delay(1000, ct);
}
}
catch (OperationCanceledException)
{
// Normal shutdown — not an error
_logger.LogInformation("Service stopping due to cancellation");
}
finally
{
// Cleanup
await CleanupAsync();
}
}Antrean Latar Belakang Berbasis Kanal
Pola yang umum digunakan: layanan latar belakang membaca dari antrean Channel, sementara titik akhir HTTP memasukkan item pekerjaan ke antrean. Dengan demikian, penanganan permintaan terpisah dari pemrosesan pekerjaan.
public class BackgroundTaskQueue
{
private readonly Channel<Func<CancellationToken, Task>> _queue
= Channel.CreateBounded<Func<CancellationToken, Task>>(100);
public ValueTask QueueAsync(Func<CancellationToken, Task> job)
=> _queue.Writer.WriteAsync(job);
public IAsyncEnumerable<Func<CancellationToken, Task>> DequeueAllAsync(
CancellationToken ct)
=> _queue.Reader.ReadAllAsync(ct);
}
// Register and use:
builder.Services.AddSingleton<BackgroundTaskQueue>();
builder.Services.AddHostedService<QueueProcessorService>();Penanganan Kesalahan pada Layanan Latar Belakang
Pengecualian yang tidak ditangani dalam ExecuteAsync dapat menghentikan layanan secara diam-diam. Bungkus perulangan utama dalam try/catch dan catat kesalahan agar layanan tetap berjalan meskipun terjadi kegagalan individual.
protected override async Task ExecuteAsync(CancellationToken ct)
{
while (!ct.IsCancellationRequested)
{
try
{
await ProcessNextBatchAsync(ct);
}
catch (OperationCanceledException) when (ct.IsCancellationRequested)
{
break; // normal shutdown
}
catch (Exception ex)
{
_logger.LogError(ex, "Background processing error. Retrying in 5s.");
await Task.Delay(5000, ct); // backoff before retry
}
}
}StopAsync dan Batas Waktu Penghentian
Ganti StopAsync untuk melakukan pembersihan. Host meneruskan token penghentian — jika pembersihan memerlukan waktu lebih lama daripada batas waktu, proses akan dihentikan tanpa memedulikan hasilnya.
public override async Task StopAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("Service is stopping...");
// Signal internal work to stop
_internalCts.Cancel();
// Wait for the Execute loop to complete (up to timeout)
await base.StopAsync(stoppingToken);
_logger.LogInformation("Service stopped");
}
// Increase the shutdown timeout if needed:
builder.Services.Configure<HostOptions>(opt =>
opt.ShutdownTimeout = TimeSpan.FromSeconds(30));Beberapa Layanan Latar Belakang
Daftarkan beberapa layanan yang di-host — semuanya berjalan secara bersamaan. Host memulainya sesuai urutan pendaftaran dan menghentikannya dalam urutan terbalik.
builder.Services.AddHostedService<DatabaseMigratorService>(); // startup task
builder.Services.AddHostedService<MetricsCollectorService>(); // continuous
builder.Services.AddHostedService<EmailNotificationService>(); // continuous
builder.Services.AddHostedService<CacheWarmupService>(); // startup task
// All run concurrently after app start
// Stopped in reverse registration order on shutdownDunia Nyata: Pekerja Pemrosesan Pesanan
Layanan latar belakang yang memproses pesanan tertunda dari antrean basis data, dengan pengaturan cakupan dan penanganan kesalahan yang tepat.
public class OrderProcessorService : BackgroundService
{
private readonly IServiceScopeFactory _factory;
private readonly ILogger<OrderProcessorService> _log;
public OrderProcessorService(IServiceScopeFactory f, ILogger<OrderProcessorService> l)
{ _factory = f; _log = l; }
protected override async Task ExecuteAsync(CancellationToken ct)
{
while (!ct.IsCancellationRequested)
{
try
{
using var scope = _factory.CreateScope();
var processor = scope.ServiceProvider.GetRequiredService<IOrderProcessor>();
int count = await processor.ProcessPendingAsync(ct);
_log.LogInformation("Processed {Count} orders", count);
}
catch (Exception ex) when (!ct.IsCancellationRequested)
{
_log.LogError(ex, "Order processing failed");
}
await Task.Delay(TimeSpan.FromSeconds(10), ct);
}
}
}Pemeriksaan Singkat
Mengapa layanan latar belakang harus menggunakan IServiceScopeFactory, bukan menyuntikkan DbContext secara langsung?
Ringkasan: IHostedService & BackgroundService
Inti pembelajaran:
IHostedService: StartAsync/StopAsync — untuk tugas mulai dan berhentiBackgroundService: perulangan ExecuteAsync — untuk pekerjaan latar belakang yang berkelanjutan- Selalu gunakan
IServiceScopeFactoryuntuk dependensi Scoped di dalam layanan latar belakang - Pantau token pembatalan pada setiap await agar penghentian dapat berlangsung secara bertahap
- Bungkus isi perulangan dalam try/catch agar layanan tidak berhenti karena kesalahan
- Gunakan
HostOptions.ShutdownTimeoutjika pembersihan memerlukan waktu lebih dari 5 detik
Belajar C# dengan tutor AI — gratis
Tulis dan jalankan kode asli di browser kamu, dapatkan bantuan instan dari tutor AI 24/7, dan lanjutkan di mana kamu tinggalkan di web atau aplikasi.
- Kursus
- 93
- Pelajaran
- 346
Pertanyaan yang Sering Diajukan
Apakah pelajaran “IHostedService & BackgroundService” gratis?
Ya — teks lengkap “IHostedService & BackgroundService” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus C# Academy, upgrade ke CoddyKit PRO. Kursus C# Academy mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “IHostedService & BackgroundService”?
Implementasikan IHostedService dan BackgroundService abstrak untuk menjalankan pekerjaan di latar belakang dalam host .NET. Kamu berlatih C# Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai C# Academy?
Tidak diperlukan pengalaman sebelumnya. C# Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 1 dari 4.
Berapa lama pelajaran “IHostedService & BackgroundService” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran C# Academy ini?
Ya. Setiap pelajaran C# Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- IHostedService & BackgroundService
- Proyek Worker Service
- Tugas Berkala & Timer
- Pekerjaan Terjadwal Quartz.NET