后台托管服务在.net core 中执行两次。有什么解决办法吗?

发布于 2025-01-15 17:21:28 字数 2274 浏览 1 评论 0原文

我在.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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

匿名。 2025-01-22 17:21:28

上述问题的根本原因是:

我们的 API 解决方案中配置了后台服务,并且 API 在多个实例上运行,因此导致多个后台服务并行运行,这在我们的案例中很容易出错。

解决方案:

  1. 要么限制正在运行的实例,但这不切实际,因为可能会导致性能问题。

  2. 后台服务应该在专用项目中配置。

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:

  1. Either limit the running instances, but that could not be practical as it may result in performance issues.

  2. Background service should have been configured in a dedicated project.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文