Bagikan melalui


IHostedService Menerapkan antarmuka

Ketika Anda membutuhkan kontrol terbatas di luar yang disediakan BackgroundService, Anda dapat menerapkan sendiri IHostedService. Antarmuka IHostedService adalah dasar untuk semua layanan yang berjalan lama di .NET. Implementasi kustom terdaftar dengan AddHostedService<THostedService>(IServiceCollection) metode ekstensi.

Dalam tutorial ini, Anda akan mempelajari cara:

  • IHostedServiceMenerapkan antarmuka , dan IAsyncDisposable .
  • Buat layanan berbasis timer.
  • Daftarkan implementasi kustom dengan injeksi dependensi dan pengelogan.

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 timer

Layanan latar belakang berbasis timer menggunakan System.Threading.Timer kelas . Timer memicu DoWork metode . Timer dinonaktifkan dan IHostLifetime.StopAsync(CancellationToken) dibuang ketika kontainer layanan dibuang pada IAsyncDisposable.DisposeAsync():

Ganti konten Worker dari templat dengan kode C# berikut, dan ganti nama file menjadi TimerService.cs:

namespace App.TimerHostedService;

public sealed class TimerService(ILogger<TimerService> logger) : IHostedService, IAsyncDisposable
{
    private readonly Task _completedTask = Task.CompletedTask;
    private int _executionCount = 0;
    private Timer? _timer;

    public Task StartAsync(CancellationToken stoppingToken)
    {
        logger.LogInformation("{Service} is running.", nameof(TimerHostedService));
        _timer = new Timer(DoWork, null, TimeSpan.Zero, TimeSpan.FromSeconds(5));

        return _completedTask;
    }

    private void DoWork(object? state)
    {
        int count = Interlocked.Increment(ref _executionCount);

        logger.LogInformation(
            "{Service} is working, execution count: {Count:#,0}",
            nameof(TimerHostedService),
            count);
    }

    public Task StopAsync(CancellationToken stoppingToken)
    {
        logger.LogInformation(
            "{Service} is stopping.", nameof(TimerHostedService));

        _timer?.Change(Timeout.Infinite, 0);

        return _completedTask;
    }

    public async ValueTask DisposeAsync()
    {
        if (_timer is IAsyncDisposable timer)
        {
            await timer.DisposeAsync();
        }

        _timer = null;
    }
}

Penting

Worker itu adalah subkelas dari BackgroundService. Sekarang, mengimplementasikan TimerServiceIHostedServiceantarmuka , dan IAsyncDisposable .

TimerService adalah sealed, dan kaskade DisposeAsync panggilan dari instansnya_timer. Untuk informasi selengkapnya tentang "pola pembuangan berkala", lihat Menerapkan DisposeAsync metode.

Ketika StartAsync dipanggil, timer dibuat, sehingga memulai timer.

Tip

Timer Tidak menunggu eksekusi DoWork sebelumnya selesai, sehingga pendekatan yang ditampilkan mungkin tidak cocok untuk setiap skenario. Interlocked.Increment digunakan untuk menaikkan penghitung eksekusi sebagai operasi atomik, yang memastikan bahwa beberapa utas tidak diperbarui _executionCount secara bersamaan.

Ganti konten yang ada Program dengan kode C# berikut:

using App.TimerHostedService;

HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services.AddHostedService<TimerService>();

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

Layanan ini terdaftar di (Program.cs) dengan AddHostedService metode ekstensi. Ini adalah metode ekstensi yang sama dengan yang Anda gunakan saat mendaftarkan BackgroundService subkelas, karena keduanya mengimplementasikan IHostedService antarmuka.

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.TimerHostedService.TimerService[0]
      TimerHostedService is running.
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: .\timer-service
info: App.TimerHostedService.TimerService[0]
      TimerHostedService is working, execution count: 1
info: App.TimerHostedService.TimerService[0]
      TimerHostedService is working, execution count: 2
info: App.TimerHostedService.TimerService[0]
      TimerHostedService is working, execution count: 3
info: App.TimerHostedService.TimerService[0]
      TimerHostedService is working, execution count: 4
info: Microsoft.Hosting.Lifetime[0]
      Application is shutting down...
info: App.TimerHostedService.TimerService[0]
      TimerHostedService 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

Ada beberapa tutorial terkait yang perlu dipertimbangkan: