gpt4 book ai didi

azure - ASP.NET Core BackgroundService 运行多次

转载 作者:行者123 更新时间:2023-12-02 06:37:29 25 4
gpt4 key购买 nike

我目前有一个带有 .NET Core SDK v5.0.403 的 ASP.NET Core 应用程序。

在此应用程序中,我定义了多个 BackgroundService,其中之一如下:

public class DueDateNotificationService : BackgroundService
{
private readonly ILogger _logger;
private readonly IServiceScopeFactory _serviceProvider;

private readonly int _actionDueDateGenerationDelay;
private readonly int _startupDelayInSeconds;

protected static int instances = 0;

public DueDateNotificationService(ILogger<DueDateNotificationService> logger,
IServiceScopeFactory serviceProvider,
IConfiguration configuration)
{
_logger = logger;
_serviceProvider = serviceProvider;

_actionDueDateGenerationDelay = configuration["BackgroundServices:DueDateNotificationService:DueDateGenerationDelay"].ToInt(240);
_startupDelayInSeconds = Math.Max(configuration["BackgroundServices:DueDateNotificationService:StartupDelayInSeconds"].ToInt(), 60);
}

/// <summary>
/// Service execution
/// </summary>
/// <param name="stoppingToken"></param>
/// <returns></returns>
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
// Adding basic data to the logging context
using (LogContext.PushProperty("AppName", "Api-DueDateNotificationService"))
{
_logger.LogInformation("DueDateNotificationService Hosted Service is starting.");
await Task.Delay(TimeSpan.FromSeconds(_startupDelayInSeconds), stoppingToken);


while (!stoppingToken.IsCancellationRequested)
{


try
{
using (var scope = _serviceProvider.CreateScope())
{
var service = scope.ServiceProvider.GetRequiredService<IMyService>();
_logger.LogInformation($"doing stuff");
service.DoStuff();

}
// waiting until we should check again
_logger.LogInformation($"Job finished at {DateTime.UtcNow}. Next job at {DateTime.UtcNow.AddMinutes(_actionDueDateGenerationDelay)}");
await Task.Delay(TimeSpan.FromMinutes(_actionDueDateGenerationDelay));
}
catch (TaskCanceledException)
{
_logger.LogWarning("The DueDateNotificationService Hosted Service was cancelled, likely because the site was shutdown (possibly due to inactivity or a force update)");
}
catch (Exception ex)
{
_logger.LogError(ex, $"Error occurred executing the automated DueDateNotificationService service.");
}
}

_logger.LogInformation("DueDateNotificationService Hosted Service is stopping.");

}
}

我的服务仅在startup.cs中的一个位置添加到DI:

EnableHostedService<DueDateNotificationService>(services, "BackgroundServices:DueDateNotificationService:Enabled");

EnabledHostedService 为:

private IServiceCollection EnableHostedService<T>(IServiceCollection services, string configurationKey) where T : class, IHostedService
{
// Background services to run
if (Configuration[configurationKey].Equals("true", StringComparison.OrdinalIgnoreCase))
{
return services.AddHostedService<T>();
}

return services;
}

这是我注册backgroundService的唯一地方,除了默认提供的之外,应用程序中的任何地方都没有autofac或自定义DI。

我的问题是,每当我的应用程序托管在 azure 应用程序服务中时,所有后台服务都会同时运行多次。

当我查看我的日志时,

DueDateNotificationService Hosted Service is starting.

至少显示两次,我的 while 循环中的所有日志也是如此(我在此处将其删除以减轻帖子的负担)。

但是当我在本地调试它时,它只运行一次,这是应该的。

当我评论我的注册行时,它根本没有启动(即使在 Azure 上)。

它可能来自什么?

谢谢

更新我什至尝试过类似的东西:

protected static int instances = 0;
....
Interlocked.Increment(ref instances);
if (instances > 1)
{
_logger.LogInformation("An instance of DueDateNotificationService is already started.");
}
else
{
MyWhileLoop();
}

仍然启动/执行多次,日志如下:

An instance of DueDateNotificationService is already started.

从不出现。

最佳答案

azure app service

这几乎肯定是由于您的应用程序正在运行多个实例。

What would be the safest way to have the backgroundservice running only once, beside going through some data persist / check in DB?

外部“租赁”是最安全的方法。您可以使用 CosmosDb/Redis 作为后端自行构建一个,也可以使用内置方法,将 Web 应用程序中的后台服务分解为 Azure WebJob 或 Azure Function。这两个服务都自动使用租约来执行计时器触发的作业。

关于azure - ASP.NET Core BackgroundService 运行多次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70867082/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com