Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Используйте службы с ограниченной областью действия в пределах
При регистрации реализаций IHostedService при использовании любого из методов расширения AddHostedService, служба регистрируется как синглтон. Могут возникнуть сценарии, где вы хотите полагаться на службу с ограниченной областью действия. Дополнительные сведения см. в разделе "Время существования службы".
В этом руководстве вы узнаете, как:
- Правильно разрешать ограниченные зависимости в одноэлементном BackgroundService.
- Делегировать работу ограниченному сервису.
- Реализовать
overrideиз BackgroundService.StopAsync(CancellationToken).
Подсказка
Все примеры исходного кода из "Workers in .NET" доступны в обзоре примеров для загрузки. Дополнительные сведения см. в разделе Примеры кода: рабочие процессы в .NET.
Предпосылки
- Пакет SDK .NET 8.0 или более поздней версии
- Интегрированная среда разработки .NET (IDE), например Visual Studio
Создание нового проекта
Чтобы создать проект рабочей службы с помощью 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 CreateAsyncScope. По умолчанию для размещаемой службы область видимости не создается. В службе с ограниченной областью видимости содержится логика фоновой задачи.
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)
{
await using AsyncServiceScope scope = serviceScopeFactory.CreateAsyncScope();
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 используется для создания асинхронной области видимости. Из AsyncServiceScopeIScopedProcessingService разрешён. Метод 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 в окне консоли, чтобы сообщить об отмене.