[英]Multiple Background Services in .NET Core
在 .NET 6 中創建多個后台任務,這些任務在功能方面相互獨立,並根據計划的時間並行/同時運行。 使用Worker class 模板,我能夠創建多個托管/后台服務,並且它們按預期運行。
但是services.AddHostedService<Worker>();
將被視為 Singleton class 並且我們需要解決作用域依賴性以使服務成為作用域,與作用域服務文檔中的相同。 根據上面鏈接中的示例,示例代碼如下所示,Scoped 服務的接口
namespace App.ScopedService;
public interface IScopedProcessingService
{
Task DoWorkAsync(CancellationToken stoppingToken);
}
和接口的默認實現
namespace App.ScopedService;
public class DefaultScopedProcessingService : IScopedProcessingService
{
private int _executionCount;
private readonly ILogger<DefaultScopedProcessingService> _logger;
public DefaultScopedProcessingService(
ILogger<DefaultScopedProcessingService> logger) =>
_logger = logger;
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);
}
}
}
這是后台服務實現
namespace App.ScopedService;
public sealed class ScopedBackgroundService : BackgroundService
{
private readonly IServiceProvider _serviceProvider;
private readonly ILogger<ScopedBackgroundService> _logger;
public ScopedBackgroundService(
IServiceProvider serviceProvider,
ILogger<ScopedBackgroundService> logger) =>
(_serviceProvider, _logger) = (serviceProvider, logger);
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation(
$"{nameof(ScopedBackgroundService)} is running.");
await DoWorkAsync(stoppingToken);
}
private async Task DoWorkAsync(CancellationToken stoppingToken)
{
_logger.LogInformation(
$"{nameof(ScopedBackgroundService)} is working.");
using (IServiceScope scope = _serviceProvider.CreateScope())
{
IScopedProcessingService scopedProcessingService =
scope.ServiceProvider.GetRequiredService<IScopedProcessingService>();
await scopedProcessingService.DoWorkAsync(stoppingToken);
}
}
public override async Task StopAsync(CancellationToken stoppingToken)
{
_logger.LogInformation(
$"{nameof(ScopedBackgroundService)} is stopping.");
await base.StopAsync(stoppingToken);
}
}
和 Program.cs 將如下所示
using App.ScopedService;
using IHost host = Host.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{
services.AddHostedService<ScopedBackgroundService>();
services.AddScoped<IScopedProcessingService, DefaultScopedProcessingService>();
})
.Build();
await host.RunAsync();
如果我有另一個后台服務,那么我可以重用哪些代碼以及如何解決范圍服務?
您可以創建多個實現 IHostedService 接口的服務,然后像這樣注冊它們:
builder.Services.AddHostedService<HostedServiceA>();
builder.Services.AddHostedService<HostedServiceB>();
builder.Services.AddHostedService<HostedServiceC>();
如果要訪問 singleton 中的范圍服務,最簡單的方法是在構造函數中注入IServiceScopeFactory :
public HostedServiceA(IServiceScopeFactory serviceScopeFactory)
{
_serviceScopeFactory = serviceScopeFactory ?? throw new ArgumentNullException(nameof(serviceScopeFactory));
}
然后您可以通過調用以下方法訪問方法內的作用域服務:
using var scope = _serviceScopeFactory.CreateScope();
var someScopedService = scope.ServiceProvider.GetService<ISomeScopedService>();
var someOtherScopedService = scope.ServiceProvider.GetService<ISomeOtherScopedService>();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.