后台托管服务在.net core 中执行两次。有什么解决办法吗?
我在.net core 3.1中创建了一个后台托管服务,并基于CRON表达式,预计它会在所需的时间运行。即周一至周五凌晨 3 点。一切似乎都工作正常,后台服务在所需的时间运行,但是当它运行时,它总是运行两次。该应用程序托管在 IIS 上。
这是我正在使用的代码:
在启动文件中,ConfigureServices 方法:
services.AddHostedService<MyTestBackgroundHostedService>();
这是我配置的服务:
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using NCrontab;
using Serilog;
namespace MyProject
{
public class MyTestBackgroundService : BackgroundService
{
private readonly CrontabSchedule _schedule;
private readonly string _scheduleDetail;
private DateTime _nextRun;
private ILogger _logger;
public MyTestBackgroundService(ILogger logger)
{
_scheduleDetail = "0 0 3 * * 0";
_schedule = CrontabSchedule.Parse(_scheduleDetail, new CrontabSchedule.ParseOptions { IncludingSeconds = true });
_nextRun = _schedule.GetNextOccurrence(DateTime.Now);
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
do {
var now = DateTime.Now;
if (now > _nextRun) {
_logger.Information($"MyTestBackgroundService job started at {now}", now);
Process();
_logger.Information($"MyTestBackgroundService :MyTestBackgroundService job finished at {now}", now);
_nextRun = _schedule.GetNextOccurrence(DateTime.Now);
}
await Task.Delay(5000, stoppingToken);
}
while (!stoppingToken.IsCancellationRequested);
}
public override Task StartAsync(CancellationToken cancellationToken)
{
return base.StartAsync(cancellationToken);
}
public override Task StopAsync(CancellationToken cancellationToken)
{
return base.StopAsync(cancellationToken);
}
private void Process()
{
try {
// do something
}
catch (Exception ex) {
_logger.Error($"MyTestBackgroundService failed : {ex}");
}
}
}
}
I have created one background hosted service in .net core 3.1, and based on CRON expression, it is expected to run at desired time. i.e. 3 AM through Mon-Fri. Everything seems to be working fine, the background service is running at desired time, but when it runs, it always runs twice. The app is hosted on IIS.
Here is the code which I am using:
In Startup File, ConfigureServices Methods:
services.AddHostedService<MyTestBackgroundHostedService>();
Here is my service configured:
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using NCrontab;
using Serilog;
namespace MyProject
{
public class MyTestBackgroundService : BackgroundService
{
private readonly CrontabSchedule _schedule;
private readonly string _scheduleDetail;
private DateTime _nextRun;
private ILogger _logger;
public MyTestBackgroundService(ILogger logger)
{
_scheduleDetail = "0 0 3 * * 0";
_schedule = CrontabSchedule.Parse(_scheduleDetail, new CrontabSchedule.ParseOptions { IncludingSeconds = true });
_nextRun = _schedule.GetNextOccurrence(DateTime.Now);
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
do {
var now = DateTime.Now;
if (now > _nextRun) {
_logger.Information(quot;MyTestBackgroundService job started at {now}", now);
Process();
_logger.Information(quot;MyTestBackgroundService :MyTestBackgroundService job finished at {now}", now);
_nextRun = _schedule.GetNextOccurrence(DateTime.Now);
}
await Task.Delay(5000, stoppingToken);
}
while (!stoppingToken.IsCancellationRequested);
}
public override Task StartAsync(CancellationToken cancellationToken)
{
return base.StartAsync(cancellationToken);
}
public override Task StopAsync(CancellationToken cancellationToken)
{
return base.StopAsync(cancellationToken);
}
private void Process()
{
try {
// do something
}
catch (Exception ex) {
_logger.Error(quot;MyTestBackgroundService failed : {ex}");
}
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
上述问题的根本原因是:
我们的 API 解决方案中配置了后台服务,并且 API 在多个实例上运行,因此导致多个后台服务并行运行,这在我们的案例中很容易出错。
解决方案:
要么限制正在运行的实例,但这不切实际,因为可能会导致性能问题。
后台服务应该在专用项目中配置。
Root cause for above problem was:
Background service is configured in our API solution, and API was running on multiple instances, hence resulting in multiple background services running in parallel, which was error prone in our case.
Solution:
Either limit the running instances, but that could not be practical as it may result in performance issues.
Background service should have been configured in a dedicated project.