Aracılığıyla paylaş


Arabirimi uygulama IHostedService

Sağlanan BackgroundServicedeğerinin ötesinde sınırlı denetime ihtiyacınız olduğunda kendi IHostedServiceuygulamanızı sağlayabilirsiniz. IHostedService Arabirim, .NET'te uzun süre çalışan tüm hizmetlerin temelini oluşturur. Özel uygulamalar uzantı yöntemiyle AddHostedService<THostedService>(IServiceCollection) kaydedilir.

Bu öğreticide aşağıdakilerin nasıl yapılacağını öğreneceksiniz:

  • IHostedServiceve IAsyncDisposable arabirimlerini uygulayın.
  • Zamanlayıcı tabanlı bir hizmet oluşturun.
  • Bağımlılık ekleme ve günlüğe kaydetme ile özel uygulamayı kaydedin.

Bahşiş

".NET'te Çalışanlar" örnek kaynak kodunun tümü, indirilebilmeniz için Samples Browser'da bulunur. Daha fazla bilgi için bkz . Kod örneklerine göz atma: .NET'te çalışanlar.

Önkoşullar

Yeni proje oluşturma

Visual Studio ile yeni bir Çalışan Hizmeti projesi oluşturmak için Dosya>Yeni>Proje... seçeneğini belirlemeniz gerekir. Yeni proje oluştur iletişim kutusunda "Çalışan Hizmeti" araması yapın ve Çalışan Hizmeti şablonu'na tıklayın. .NET CLI kullanmayı tercih ediyorsanız, sık kullandığınız terminali çalışma dizininde açın. dotnet new komutunu çalıştırın ve öğesini istediğiniz proje adıyla değiştirin<Project.Name>.

dotnet new worker --name <Project.Name>

.NET CLI yeni çalışan hizmeti projesi komutu hakkında daha fazla bilgi için bkz . dotnet new worker.

Bahşiş

Visual Studio Code kullanıyorsanız tümleşik terminalden .NET CLI komutlarını çalıştırabilirsiniz. Daha fazla bilgi için bkz . Visual Studio Code: Tümleşik Terminal.

Zamanlayıcı hizmeti oluşturma

Zamanlayıcı tabanlı arka plan hizmeti sınıfını System.Threading.Timer kullanır. Zamanlayıcı yöntemini tetikler DoWork . Zamanlayıcı üzerinde devre dışı bırakılır IHostLifetime.StopAsync(CancellationToken) ve hizmet kapsayıcısı üzerinde IAsyncDisposable.DisposeAsync()atıldığında atılır:

şablonundaki Worker içeriğini aşağıdaki C# koduyla değiştirin ve dosyayı TimerService.cs olarak yeniden adlandırın:

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;
    }
}

Önemli

öğesinin WorkerBackgroundServicealt sınıfıydı. Şimdi, TimerService hem IHostedServiceve IAsyncDisposable arabirimlerini uygular.

TimerService, sealedve örneğinden _timer çağrıyı DisposeAsync basamaklar. "Basamaklı atma deseni" hakkında daha fazla bilgi için bkz. Yöntem uygulamaDisposeAsync.

Çağrıldığında StartAsync zamanlayıcı örneği oluşturulur, böylece zamanlayıcı başlatılır.

Bahşiş

Timer önceki yürütmelerinin DoWork tamamlanmasını beklemez, bu nedenle gösterilen yaklaşım her senaryo için uygun olmayabilir. Interlocked.Increment , birden çok iş parçacığının eşzamanlı olarak güncelleştirilmesini _executionCount engelleyen bir atomik işlem olarak yürütme sayacını artırmak için kullanılır.

Mevcut Program içeriği aşağıdaki C# koduyla değiştirin:

using App.TimerHostedService;

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

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

Hizmet , uzantı yöntemiyle AddHostedService (Program.cs) dosyasına kaydedilir. Bu, her ikisi de arabirimi uyguladığından, alt sınıfları kaydederken BackgroundService kullandığınız uzantı yöntemiyle IHostedService aynıdır.

Hizmetleri kaydetme hakkında daha fazla bilgi için bkz . .NET'te bağımlılık ekleme.

Hizmet işlevselliğini doğrulama

Uygulamayı Visual Studio'dan çalıştırmak için F5'i seçin veya Hata AyıklamaYı>Başlat Hata Ayıklama menü seçeneğini belirleyin. .NET CLI kullanıyorsanız, çalışma dizininden komutunu çalıştırın dotnet run :

dotnet run

.NET CLI çalıştırma komutu hakkında daha fazla bilgi için bkz . dotnet run.

Uygulamanın birkaç yürütme sayısı artışı oluşturmak için bir bit boyunca çalışmasına izin verin. Aşağıdakine benzer bir çıkış görürsünüz:

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.

Uygulamayı Visual Studio'dan çalıştırıyorsanız Hata Ayıklama Hata Ayıklamayı>Durdur... öğesini seçin. Alternatif olarak, iptal sinyali almak için konsol penceresinden Ctrl + C'yi seçin.

Ayrıca bkz.

Dikkate alınması gereken birkaç ilgili öğretici vardır: