ASP.Net Core IHosted background service внезапно выключается

Ищу помощи, уже всю голову сломал. В общем есть приложение ASP.NET Core Razor Pages (.Net 5), хостится на IIS. У приложения есть фоновый сервис, который по расписанию запускает несколько методов. При выполнении приложения происходит 2 проблемы:

  1. Фоновый сервис прекращает работу через 20 минут (IIS настраивал на бесперебойную работу).
  2. Фоновый сервис при выполнении определенных действий выключается.

При этом, если приложение запустить из командной строки, то все работает прекрасно и без сбоев. Пробовал, оборачивать все в try catch для обработки исключений, но их нет. При поиске проблем обнаружил, что если в методе CheckChanges в цикле foreach (var ca in result.УдостоверяющийЦентр.Where(x=>x.РеестровыйНомер != 0)) закоментить исполянемый код, то сервис не падает. P.S. Проблема только в IIS.

В логах приложения:

info: CronJobUpdateCA[0]

08:50:00 CronJob is working.

info: Microsoft.Hosting.Lifetime[0]

Application is shutting down...

Вот код сервиса:

BackgroundService.cs

public abstract class BackgroundService : IHostedService
{

private Task _executingTask;

private readonly CancellationTokenSource _stoppingCts =
                                               new CancellationTokenSource();

public virtual Task StartAsync(CancellationToken cancellationToken)
{
   _executingTask = ExecuteAsync(_stoppingCts.Token);

    if (_executingTask.IsCompleted)
    {
        return _executingTask;
    }

    // Otherwise it's running
    return Task.CompletedTask;
}

public virtual async Task StopAsync(CancellationToken cancellationToken)
{
    // Stop called without start
    if (_executingTask == null)
    {
        return;
    }

    try
    {
        _stoppingCts.Cancel();
    }
    
    finally
    {
        await Task.WhenAny(_executingTask, Task.Delay(5000,
                                                  cancellationToken));
    }
}

protected virtual async Task ExecuteAsync(CancellationToken stoppingToken)
{
    do
    {
        await Process();

        await Task.Delay(30000, stoppingToken); //5 seconds delay
    }
    
    while (!stoppingToken.IsCancellationRequested);
    
}

protected abstract Task Process();

}

ScopedProcessor.cs

public abstract class ScopedProcessor : BackgroundService
{
private readonly IServiceScopeFactory _serviceScopeFactory;

public ScopedProcessor(IServiceScopeFactory serviceScopeFactory) : base()
{
    _serviceScopeFactory = serviceScopeFactory;
}

protected override async Task Process()
{
    using (var scope = _serviceScopeFactory.CreateScope())
    {
        await ProcessInScope(scope.ServiceProvider);
    }
}

public abstract Task ProcessInScope(IServiceProvider serviceProvider);

}

SchedulerProcessor.cs

public abstract class ScheduledProcessor : ScopedProcessor

{ private CrontabSchedule _schedule; private DateTime _nextRun;

protected abstract string Schedule { get; }
public ScheduledProcessor(IServiceScopeFactory serviceScopeFactory) : base(serviceScopeFactory)
{
    
    _schedule = CrontabSchedule.Parse(Schedule);
    _nextRun = _schedule.GetNextOccurrence(DateTime.Now);
}

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
    do
    {
        var now = DateTime.Now;
        if (now > _nextRun)
        {
            await Process();
            _nextRun = _schedule.GetNextOccurrence(DateTime.Now);
        }
        await Task.Delay(5000, stoppingToken); //5 seconds delay
    }
    while (!stoppingToken.IsCancellationRequested);
}

}

SchedulerTask.cs

public class ScheduleTask : ScheduledProcessor

{

private readonly IConfiguration _configuration;

public ScheduleTask(IServiceScopeFactory serviceScopeFactory, IConfiguration configuration) : base(serviceScopeFactory)
{
   
    _configuration = configuration;
}

protected override string Schedule => "*/2 * * * *";

public override Task ProcessInScope(IServiceProvider serviceProvider)
{
    

    var updater = new CAUpdater(_configuration);
  
        updater.Test();
    return Task.CompletedTask;
}

метод Test

public void Test()
    {
        
        ReadFile(); //Десериализация xml файла.
        CheckChanges();
    }

метод CheckChanges()

private void CheckChanges()
    {
        try
        {
            var context = new ApplicationContext();
            Update upd = new Update();
            upd.Date = result?.Дата ?? DateTime.Now;
            upd.Version = result?.Версия ?? 0;
            upd.FileName = fileName;
            upd.Error = _errorBody.ToString();
            update = context.Updates.Add(upd).Entity;
            
            if (result == null)
            {
                context.SaveChanges();
                return;
            }
            
            foreach (var ca in context.CA.Where(x => !x.Deleted).ToList())
            {
                if (result.УдостоверяющийЦентр.All(x => x.РеестровыйНомер != 0 ? x.РеестровыйНомер != ca.Id : x.КраткоеНазвание != ca.Name))
                {
                    ca.Deleted = true;
                    context.CA.Update(ca);
                    
                    context.СaChanges.Add(new СaChange()
                    {
                        Update = update,
                        CA = ca,
                        Action = "Delete",
                    });

                }
            }
            
            foreach (var ca in result.УдостоверяющийЦентр.Where(x=>x.РеестровыйНомер != 0))
            {   
                var item =
                    ca.РеестровыйНомер != 0
                        ? context.CA.FirstOrDefault(x => x.Id == ca.РеестровыйНомер)
                        : context.CA.FirstOrDefault(x => x.Name == ca.КраткоеНазвание);
                // дальше идет код......
            }
                }

Ответы (0 шт):