Разделите их на отдельные функции и выполняйте в соответствии с расписаниями из функций Azure. Больше не нужно беспокоиться об утечках памяти, а сложность невелика.
ая версия - как мне (в 2017 году, после выпуска .NET Core 1.1) запускать повторяющиеся задачи в .NET Coreконсольное приложение сВнедрение зависимости Microsoft?
Длинная история и фрагменты кода.ЦельУ меня есть 4 (и будет больше) сервисов, каждый из которых имеет, скажем, один метод, который выполняет определенную изолированную задачу и взаимодействует с базой данных. В частности, у меня есть один сервис, который удаляет старые данные из базы данных, один сервис, который «кэширует» данные (выполняется через данные в БД и сохраняет агрегированные результаты в другой таблице), один, который генерирует случайные данные и так далее ... Идея состоит в том, чтобы запускать эти задачи с разными интервалами, скажем, каждые 20 секунд или один раз в день.
Текущая грязная реализацияУ меня есть сервис, который для каждой задачи имеетwhile(true)
цикл, который порождает сервис с DI, запускает задачу,Thread.Sleep(interval)
, проверяет условие выхода (общеклассный флаг) иcontinue/break
, Большинство методовasync
.
Прежде всего, я знаю, чтоwhile(true)
а такжеThread.Sleep(interval)
это огромный взлом (технический долг). Во-вторых, у меня утечка памяти, и я чувствую, что способ, которым я порождаю / уничтожаю сервис, как-то связан с этим. Наконец, код сталкивается со случайными ошибками, и все исключения проглатываются. Я не могу поймать их любым известным мне способом.
Я хочу достичь цели, но если возможно
избегайте больших рамок, таких как Hangfire и Quartz. Я чувствую, что мне не нужна доля того, что они могут.оставьте приложение консольным. Хотя это «помощник» для проекта ASP, я хочу, чтобы оно было консольным приложением и могло запускаться какdotnet daemons.dll
и он делает свою работу до бесконечности, пока яCtrl+C
Это. Также не должно расти потребление памяти и процессора / потоков. Это нормально, если он съедает значительный объем оперативной памяти, если это стабильное число.использовать Microsoft DI. Вот как все мои услуги построены.держать мои услугиasync
, Я могу использовать их в различных сценариях, включая модульное тестирование.Фрагменты кодаПример того, как я запускаю повторяющуюся задачу:
private async Task RunCacheServiceAsync()
{
// Make sure the service is set to run.
_status[ServiceManagerServices.Cache] = true;
_logger.LogInformation(LoggingEvents.ServiceManager.AsInt(), "Cache service started.");
while (true)
{
var metrics = await _serviceProvider
.GetRequiredService<DataContext>()
.Metrics
.ToListAsync();
// Run the tasks
var tasks = metrics
.Select(
(metric) =>
Task.Factory.StartNew(async () =>
{
await _serviceProvider
.GetRequiredService<ICacheService>()
.CacheMetric(metric);
})
);
// Wait completion of all tasks
await Task.WhenAll(tasks.ToArray());
// Wait
Thread.Sleep(_intervals[ServiceManagerServices.Cache]);
// Check exit condition
if (!_status[ServiceManagerServices.Cache])
{
break;
}
}
}
Пример задачи, которую мне нужно сделать периодической:
public async Task CleanDataPointsAsync()
{
var toTimestamp = DateTime.Now - _maxAge;
// remove data points of all types
_context.RemoveRange(
_context.NumericDataPoints.Where(dp => dp.Timestamp < toTimestamp)
);
await _context.SaveChangesAsync();
_logger.LogInformation(LoggingEvents.Clean.AsInt(), "Cleaned old data.");
}
ВопросПожалуйста, предложите общий подход, который я могу использовать для достижения цели с учетом ограничений. Любые отзывы о размещенном коде и аргументации приветствуются!