c# - 在 .net 核心控制台应用程序中开始启动作用域托管服务实例
问题描述
在 .net 核心应用程序中启动多个托管服务的最佳方式是什么?托管服务的数量在运行时会发生变化,并且在启动新的托管服务实例时需要一个参数。我想将它们实现为范围托管服务:
internal interface IScopedProcessingService
{
Task DoWork(CancellationToken stoppingToken);
}
internal class ScopedProcessingService : IScopedProcessingService
{
private int executionCount = 0;
private readonly ILogger _logger;
public ScopedProcessingService(ILogger<ScopedProcessingService> logger)
{
_logger = logger;
}
public async Task DoWork(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
executionCount++;
_logger.LogInformation(
"Scoped Processing Service is working. Count: {Count}", executionCount);
await Task.Delay(10000, stoppingToken);
}
}
}
--
public class ConsumeScopedServiceHostedService : BackgroundService
{
private readonly ILogger<ConsumeScopedServiceHostedService> _logger;
public ConsumeScopedServiceHostedService(IServiceProvider services,
ILogger<ConsumeScopedServiceHostedService> logger)
{
Services = services;
_logger = logger;
}
public IServiceProvider Services { get; }
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation(
"Consume Scoped Service Hosted Service running.");
await DoWork(stoppingToken);
}
private async Task DoWork(CancellationToken stoppingToken)
{
_logger.LogInformation(
"Consume Scoped Service Hosted Service is working.");
using (var scope = Services.CreateScope())
{
var scopedProcessingService =
scope.ServiceProvider
.GetRequiredService<IScopedProcessingService>();
await scopedProcessingService.DoWork(stoppingToken);
}
}
public override async Task StopAsync(CancellationToken stoppingToken)
{
_logger.LogInformation(
"Consume Scoped Service Hosted Service is stopping.");
await Task.CompletedTask;
}
}
例如,我想启动多个实例,ScopedProcessingService
这些实例将处理不同的任务(长时间运行)。
解决方案
你能用下面的方法替换你的 DoWork 方法并重试吗
private async Task DoWork(CancellationToken stoppingToken)
{
_logger.LogInformation(
"Consume Scoped Service Hosted Service is working.");
using (var scope = Services.CreateScope())
{
var scopedProcessingService =
scope.ServiceProvider
.GetServices<IScopedProcessingService>();
foreach (var service in scopedProcessingService)
{
await scopedProcessingService.DoWork(stoppingToken);
}
}
}
推荐阅读
- c# - 获取 c# 的碰撞形状的高度(不是 gdscript)
- html - 是否可以为 html 页面内的链接创建条件逻辑
- ruby - Lambda ArgumentError:找不到登录名——扩展“~”
- c++ - 无法使用来自 GtkSpinButton 小部件的用户输入修改全局整数变量
- c - cgo 将 gobytes 复制到 c 数组中
- flutter - 颤振 - 类型“预订”不是“地图”类型的子类型
' 在类型转换中 - python - 根据字典的嵌套值在列表中查找嵌套字典的索引
- matplotlib - 端点上的 Matplotlib x 轴日期
- javascript - 如何根据元素列表以编程方式形成矩阵线?
- firebase - Firebase 函数不会部署在 Github Actions 上