реализация IHostedService, system.threading.timer

Задача следующая: необходимо проверять доступность web ресурсов, у каждого ресурса есть свой период для проверки. Проверку нужно выполнять в фоновом потоке. Вот мой код, реализующий интерфейс Ihostedservice:

public class WebSitesAvailabilityHostedService : IHostedService, IDisposable
{
    private Timer _timer = null!;
    private Timer[] _timers = null;

    private readonly IServiceScopeFactory _scopeFactory;

    public WebSitesAvailabilityHostedService(IServiceScopeFactory scopeFactory)
    {
        _scopeFactory=scopeFactory;
    }

    public Task StartAsync(CancellationToken stoppingToken)
    {
        using (var scope = _scopeFactory.CreateScope())
        {
            using (var db = scope.ServiceProvider.GetService<ApplicationContext>())
            {
                var i = 0;

                _timers = new Timer[db.Sites.Count()];

                foreach (var site in db.Sites)
                {
                    _timers[i] = new Timer(DoWork, site, TimeSpan.Zero, TimeSpan.FromSeconds(site.Period));

                    i++;
                }
            }
        }

        return Task.CompletedTask;
    }
    private async void DoWork(object? state)
    {
        var site = (Sites)state;


        {
            try
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(site.Url);
                //request.Timeout = 3000;
                request.AllowAutoRedirect = false; // find out if this site is up and don't follow a redirector
                request.Method = "HEAD";

                using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                {
                    site.IsAvailable = response.StatusCode == HttpStatusCode.OK;
                }
            }
            catch (Exception ex)
            {
                site.IsAvailable = false;
            }
            finally
            {
                site.CheckDate = DateTime.Now;
                Debug.WriteLine($"Обработан сайт:{site.Url}");
            }

            using (var scope = _scopeFactory.CreateScope())
            {
                using (var db = scope.ServiceProvider.GetService<ApplicationContext>())
                {
                    db.Sites.Update(site);
                    await db.SaveChangesAsync();
                }
            }
        }
    }

    public Task StopAsync(CancellationToken stoppingToken)
    {
        _timer?.Change(Timeout.Infinite, 0);

        foreach (var timer in _timers)
        {
            timer?.Change(Timeout.Infinite, 0);
        }

        return Task.CompletedTask;
    }
    public void Dispose()
    {
        _timer?.Dispose();

        foreach (var timer in _timers)
        {
            timer?.Dispose();
        }
    }
}

При количестве записей больше 700, все наглухо виснет, подскажите пожалуйста, что я делаю не так?


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