реализация 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, все наглухо виснет, подскажите пожалуйста, что я делаю не так?