Бөлісу құралы:


Используйте службы с ограниченной областью действия в пределах BackgroundService

При регистрации реализаций IHostedService при использовании любого из методов расширения AddHostedService, служба регистрируется как синглтон. Могут возникнуть сценарии, где вы хотите полагаться на службу с ограниченной областью действия. Дополнительные сведения см. в разделе "Время существования службы".

В этом руководстве вы узнаете, как:

Подсказка

Все примеры исходного кода из "Workers in .NET" доступны в обзоре примеров для загрузки. Дополнительные сведения см. в разделе Примеры кода: рабочие процессы в .NET.

Предпосылки

Создание нового проекта

Чтобы создать проект рабочей службы с помощью Visual Studio, выберите Файл>Новый проект>.... В диалоговом окне Создание нового проекта найдите "Worker Service" и выберите шаблон "Служба обработчик". Если вы предпочитаете использовать интерфейс командной строки .NET, откройте любимый терминал в рабочем каталоге. Выполните команду dotnet new и замените <Project.Name> нужным именем проекта.

dotnet new worker --name <Project.Name>

Дополнительные сведения о команде создания нового проекта рабочей службы в .NET CLI см. в разделе dotnet new worker.

Подсказка

Если вы используете Visual Studio Code, вы можете запускать команды CLI .NET из интегрированного терминала. Дополнительные сведения см. в Visual Studio Code: интегрированный терминал.

Создайте службы с областью действия

Чтобы использовать службы с областью, создайте область с помощью BackgroundService API. Для размещенной службы по умолчанию не создается область. В службе с ограниченной областью видимости содержится логика фоновой задачи.

namespace App.ScopedService;

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

Предыдущий интерфейс определяет один DoWorkAsync метод. Создайте реализацию в новом классе с именем DefaultScopedProcessingService.cs:

namespace App.ScopedService;

public sealed class DefaultScopedProcessingService(
    ILogger<DefaultScopedProcessingService> logger) : IScopedProcessingService
{
    private readonly string _instanceId = Guid.NewGuid().ToString();

    public Task DoWorkAsync(CancellationToken stoppingToken)
    {
        logger.LogInformation(
            "{ServiceName} doing work, instance ID: {Id}",
            nameof(DefaultScopedProcessingService),
            _instanceId);

        return Task.CompletedTask;
    }
}
  • Объект ILogger внедряется в службу с помощью основного конструктора.
  • Метод DoWorkAsync возвращает Task и принимает значение CancellationToken.
    • Метод регистрирует идентификатор экземпляра— _instanceId назначается при создании экземпляра класса.

Переписать класс Worker

Замените существующий Worker класс следующим кодом C# и переименуйте файл в 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);

        while (!stoppingToken.IsCancellationRequested)
        {
            using IServiceScope scope = serviceScopeFactory.CreateScope();

            IScopedProcessingService scopedProcessingService =
                scope.ServiceProvider.GetRequiredService<IScopedProcessingService>();

            await scopedProcessingService.DoWorkAsync(stoppingToken);

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

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

        await base.StopAsync(stoppingToken);
    }
}

В приведенном выше коде, пока stoppingToken не отменен, IServiceScopeFactory используется для создания области. Из IServiceScopeIScopedProcessingService разрешён. Метод DoWorkAsync ожидается, и stoppingToken передается методу. Наконец, выполнение отложено в течение 10 секунд, и цикл продолжается. Каждый раз при DoWorkAsync вызове метода создается новый экземпляр DefaultScopedProcessingService и регистрируется идентификатор экземпляра.

Замените содержимое файла Program.cs шаблона следующим кодом C#:

using App.ScopedService;

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

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

Службы зарегистрированы в (Program.cs). Хостинговая служба зарегистрирована с помощью метода расширения AddHostedService.

Дополнительные сведения о регистрации служб см. в статье внедрение зависимостей в .NET.

Проверка функциональности службы

Чтобы запустить приложение из Visual Studio, выберите F5 или выберите > пункт меню "Начать отладку". Если вы используете интерфейс командной строки .NET, выполните dotnet run команду из рабочего каталога:

dotnet run

Дополнительные сведения о команде выполнения .NET CLI см. в разделе dotnet run.

Позвольте приложению немного поработать, чтобы создать несколько вызовов DoWorkAsync, что позволит зарегистрировать новые идентификаторы экземпляров. Вы увидите выходные данные, аналогичные следующим журналам:

info: App.ScopedService.ScopedBackgroundService[0]
      ScopedBackgroundService is running.
info: App.ScopedService.DefaultScopedProcessingService[0]
      DefaultScopedProcessingService doing work, instance ID: 8986a86f-b444-4139-b9ea-587daae4a6dd
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 doing work, instance ID: 07a4a760-8e5a-4c0a-9e73-fcb2f93157d3
info: App.ScopedService.DefaultScopedProcessingService[0]
      DefaultScopedProcessingService doing work, instance ID: c847f432-acca-47ee-8720-1030859ce354
info: Microsoft.Hosting.Lifetime[0]
      Application is shutting down...
info: App.ScopedService.ScopedBackgroundService[0]
      ScopedBackgroundService is stopping.

Если приложение запущено в Visual Studio, выберите "Остановить отладку>...". Кроме того, нажмите клавиши CTRL + C в окне консоли, чтобы сообщить об отмене.

См. также