Bagikan melalui


Menggunakan layanan terlingkup dalam BackgroundService

Ketika Anda mendaftarkan implementasi menggunakan IHostedService salah AddHostedService satu metode ekstensi - layanan terdaftar sebagai singleton. Mungkin ada skenario di mana Anda ingin mengandalkan layanan tercakup. Untuk informasi selengkapnya, lihat Injeksi dependensi di .NET: Masa pakai layanan.

Dalam tutorial ini, Anda akan mempelajari cara:

Tip

Semua kode sumber contoh "Pekerja di .NET" tersedia di Browser Sampel untuk diunduh. Untuk informasi selengkapnya, lihat Menelusuri sampel kode: Pekerja di .NET.

Prasyarat

Membuat proyek baru

Untuk membuat proyek Layanan Pekerja baru dengan Visual Studio, Anda akan memilih File>Proyek Baru>....Dari dialog Buat proyek baru untuk "Layanan Pekerja", dan pilih templat Layanan Pekerja. Jika Anda lebih suka menggunakan .NET CLI, buka terminal favorit Anda di direktori kerja. Jalankan dotnet new perintah , dan ganti dengan nama proyek yang <Project.Name> Anda inginkan.

dotnet new worker --name <Project.Name>

Untuk informasi selengkapnya tentang perintah proyek layanan pekerja baru .NET CLI, lihat dotnet pekerja baru.

Tip

Jika Anda menggunakan Visual Studio Code, Anda dapat menjalankan perintah .NET CLI dari terminal terintegrasi. Untuk informasi selengkapnya, lihat Visual Studio Code: Terminal Terintegrasi.

Membuat layanan terlingkup

Untuk menggunakan layanan terlingkup dalam BackgroundService, buat cakupan. Tidak ada cakupan yang dibuat untuk layanan yang dihosting secara default. Layanan latar belakang tercakup berisi logika tugas latar belakang.

namespace App.ScopedService;

public interface IScopedProcessingService
{
    Task DoWorkAsync(CancellationToken stoppingToken);
}

Antarmuka sebelumnya mendefinisikan satu DoWorkAsync metode. Untuk menentukan implementasi default:

  • Layanan ini asinkron. Metode mengembalikan DoWorkAsyncTask. Untuk tujuan demonstrasi, penundaan sepuluh detik ditunggu dalam metode .DoWorkAsync
  • ILogger Disuntikkan ke dalam layanan.:
namespace App.ScopedService;

public sealed class DefaultScopedProcessingService(
    ILogger<DefaultScopedProcessingService> logger) : IScopedProcessingService
{
    private int _executionCount;

    public async Task DoWorkAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            ++ _executionCount;

            logger.LogInformation(
                "{ServiceName} working, execution count: {Count}",
                nameof(DefaultScopedProcessingService),
                _executionCount);

            await Task.Delay(10_000, stoppingToken);
        }
    }
}

Layanan yang dihosting membuat cakupan untuk menyelesaikan layanan latar belakang terlingkup untuk memanggil metodenya DoWorkAsync . DoWorkAsyncTaskmengembalikan , yang ditunggu dalam ExecuteAsync:

Menulis ulang kelas Pekerja

Ganti kelas yang ada Worker dengan kode C# berikut, dan ganti nama file menjadi ScopedBackgroundService.cs:

namespace App.ScopedService;

public sealed class ScopedBackgroundService(
    IServiceScopeFactory serviceScopeFactory,
    ILogger<ScopedBackgroundService> logger) : BackgroundService
{
    private const string ClassName = nameof(ScopedBackgroundService);

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        logger.LogInformation(
            "{Name} is running.", ClassName);

        await DoWorkAsync(stoppingToken);
    }

    private async Task DoWorkAsync(CancellationToken stoppingToken)
    {
        logger.LogInformation(
            "{Name} is working.", ClassName);

        using (IServiceScope scope = serviceScopeFactory.CreateScope())
        {
            IScopedProcessingService scopedProcessingService =
                scope.ServiceProvider.GetRequiredService<IScopedProcessingService>();

            await scopedProcessingService.DoWorkAsync(stoppingToken);
        }
    }

    public override async Task StopAsync(CancellationToken stoppingToken)
    {
        logger.LogInformation(
            "{Name} is stopping.", ClassName);

        await base.StopAsync(stoppingToken);
    }
}

Dalam kode sebelumnya, cakupan eksplisit dibuat dan IScopedProcessingService implementasi diselesaikan dari pabrik cakupan layanan injeksi dependensi. Instans layanan yang diselesaikan dilingkup, dan metodenya DoWorkAsync ditunggu.

Ganti konten file Program.cs templat dengan kode C# berikut:

using App.ScopedService;

HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services.AddHostedService<ScopedBackgroundService>();
builder.Services.AddScoped<IScopedProcessingService, DefaultScopedProcessingService>();

IHost host = builder.Build();
host.Run();

Layanan terdaftar di (Program.cs). Layanan yang dihosting terdaftar dengan AddHostedService metode ekstensi.

Untuk informasi selengkapnya tentang mendaftarkan layanan, lihat Injeksi dependensi di .NET.

Memverifikasi fungsionalitas layanan

Untuk menjalankan aplikasi dari Visual Studio, pilih F5 atau pilih opsi menu Debug>Mulai Debugging . Jika Anda menggunakan .NET CLI, jalankan dotnet run perintah dari direktori kerja:

dotnet run

Untuk informasi selengkapnya tentang perintah jalankan .NET CLI, lihat dotnet run.

Biarkan aplikasi berjalan sedikit untuk menghasilkan beberapa kenaikan jumlah eksekusi. Anda akan melihat output yang mirip dengan yang berikut ini:

info: App.ScopedService.ScopedBackgroundService[0]
      ScopedBackgroundService is running.
info: App.ScopedService.ScopedBackgroundService[0]
      ScopedBackgroundService is working.
info: App.ScopedService.DefaultScopedProcessingService[0]
      DefaultScopedProcessingService working, execution count: 1
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
      Content root path: .\scoped-service
info: App.ScopedService.DefaultScopedProcessingService[0]
      DefaultScopedProcessingService working, execution count: 2
info: App.ScopedService.DefaultScopedProcessingService[0]
      DefaultScopedProcessingService working, execution count: 3
info: App.ScopedService.DefaultScopedProcessingService[0]
      DefaultScopedProcessingService working, execution count: 4
info: Microsoft.Hosting.Lifetime[0]
      Application is shutting down...
info: App.ScopedService.ScopedBackgroundService[0]
      ScopedBackgroundService is stopping.

Jika menjalankan aplikasi dari dalam Visual Studio, pilih Debug>Hentikan Penelusuran Kesalahan.... Atau, pilih Ctrl + C dari jendela konsol untuk memberi sinyal pembatalan.

Baca juga