Udostępnij za pośrednictwem


Korzystanie z usług o określonym zakresie w ramach elementu BackgroundService

Podczas rejestrowania IHostedService implementacji przy użyciu dowolnej z AddHostedService metod rozszerzenia usługa jest zarejestrowana jako pojedyncza. Mogą istnieć scenariusze, w których chcesz polegać na usłudze o określonym zakresie. Aby uzyskać więcej informacji, zobacz Wstrzykiwanie zależności na platformie .NET: okresy istnienia usługi.

Z tego samouczka dowiesz się, jak wykonywać następujące czynności:

Napiwek

Cały przykładowy kod źródłowy "Pracownicy na platformie .NET" jest dostępny w przeglądarce Samples Browser do pobrania. Aby uzyskać więcej informacji, zobacz Przeglądanie przykładów kodu: Procesy robocze na platformie .NET.

Wymagania wstępne

Tworzenie nowego projektu

Aby utworzyć nowy projekt usługi roboczej za pomocą programu Visual Studio, wybierz pozycję Plik>nowy>projekt....W oknie dialogowym Tworzenie nowego projektu wyszukaj frazę "Usługa procesu roboczego" i wybierz szablon Usługa procesu roboczego. Jeśli wolisz użyć interfejsu wiersza polecenia platformy .NET, otwórz swój ulubiony terminal w katalogu roboczym. dotnet new Uruchom polecenie i zastąp element <Project.Name> odpowiednią nazwą projektu.

dotnet new worker --name <Project.Name>

Aby uzyskać więcej informacji na temat polecenia nowego projektu usługi roboczej interfejsu wiersza polecenia platformy .NET, zobacz dotnet new worker (dotnet new worker).

Napiwek

Jeśli używasz programu Visual Studio Code, możesz uruchomić polecenia interfejsu wiersza polecenia platformy .NET z poziomu zintegrowanego terminalu. Aby uzyskać więcej informacji, zobacz Visual Studio Code: Zintegrowany terminal.

Tworzenie usług o określonym zakresie

Aby użyć usług o określonym zakresie w ramach elementu BackgroundService, utwórz zakres. Domyślnie dla hostowanej usługi nie jest tworzony żaden zakres. Usługa w tle o określonym zakresie zawiera logikę zadania w tle.

namespace App.ScopedService;

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

Powyższy interfejs definiuje jedną DoWorkAsync metodę. Aby zdefiniować domyślną implementację:

  • Usługa jest asynchroniczna. Metoda DoWorkAsync zwraca wartość Task. W celach demonstracyjnych oczekuje się na opóźnienie dziesięciu sekund w metodzie DoWorkAsync .
  • Element ILogger jest wstrzykiwany do usługi.:
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);
        }
    }
}

Usługa hostowana tworzy zakres rozpoznawania zakresu usługi w tle w celu wywołania jej DoWorkAsync metody. DoWorkAsynczwraca element , który jest oczekiwany w elemecie TaskExecuteAsync:

Ponowne zapisywanie klasy Proces roboczy

Zastąp istniejącą Worker klasę następującym kodem c# i zmień nazwę pliku na 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);
    }
}

W poprzednim kodzie tworzony jest jawny zakres, a implementacja IScopedProcessingService jest rozpoznawana z fabryki zakresu usługi wstrzykiwania zależności. Rozpoznane wystąpienie usługi ma zakres, a jego DoWorkAsync metoda jest oczekiwana.

Zastąp zawartość pliku Template Program.cs następującym kodem języka C#:

using App.ScopedService;

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

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

Usługi są zarejestrowane w pliku (Program.cs). Hostowana usługa jest zarejestrowana w metodzie AddHostedService rozszerzenia.

Aby uzyskać więcej informacji na temat rejestrowania usług, zobacz Wstrzykiwanie zależności na platformie .NET.

Weryfikowanie funkcjonalności usługi

Aby uruchomić aplikację z poziomu programu Visual Studio, wybierz pozycję F5 lub wybierz opcję menu Debuguj>rozpocznij debugowanie. Jeśli używasz interfejsu wiersza polecenia platformy .NET, uruchom dotnet run polecenie z katalogu roboczego:

dotnet run

Aby uzyskać więcej informacji na temat polecenia uruchamiania interfejsu wiersza polecenia platformy .NET, zobacz dotnet run.

Pozwól aplikacji na nieco wygenerować kilka przyrostów liczby wykonań. Zostaną wyświetlone dane wyjściowe podobne do następujących:

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.

W przypadku uruchamiania aplikacji z poziomu programu Visual Studio wybierz pozycję Debuguj zatrzymaj>debugowanie.... Alternatywnie wybierz klawisze Ctrl + C z okna konsoli, aby zasygnalizować anulowanie.

Zobacz też