Куда поместить вызов метода, чтобы он выполнялся каждые 5 минут

У меня есть код ниже:

public async Task StartAsync(CancellationToken cancellationToken)
{
    var cronExpressionVal = new Timer(async e => await GetCronExpression(cancellationToken), null, TimeSpan.Zero, new TimeSpan(0, 5, 0));
}

Я пытаюсь добиться того, чтобы метод GetCronExpression запускался каждые 5 минут.

Но моя проблема в том, что когда мы впервые запускаем программу, она входит в метод StartAsync.

И выполняется успешно.

Теперь он больше не появляется в этом методе, поэтому мой метод GetCronExpression не вызывается каждые 5 минут.

Итак, мой вопрос: куда мне поместить вызов этого метода GetCronExpression, чтобы он выполнялся каждые 5 минут.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
104
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы должны сохранить ссылку на таймер, иначе он будет собран мусором:

Пока вы используете таймер, вы должны сохранять ссылку на него. Как и любой управляемый объект, Timer подлежит сборке мусора, если на него нет ссылок. Тот факт, что таймер все еще активен, не препятствует его сбору.

https://learn.microsoft.com/en-us/dotnet/api/system.threading.timer?view=net-7.0#remarks

Если это не так, я предлагаю включить больше контекста.

Ответ принят как подходящий

Чего я пытаюсь добиться, так это того, что метод GetCronExpression должен работать в каждые 5 минут.

Ну, пара способов справиться с этим. Однако самый эффективный и простой способ удовлетворить ваши требования — использовать PeriodicTimer. Главное, вам не нужно думать, где это хранить. Вы можете вызывать свой метод каждый 5 minutes временной интервал отовсюду. Это может быть в middleware или any custom class репозитории, даже из controller.

Реализация с использованием промежуточного ПО:

public class AutoTimerMiddleware
    {
        private readonly RequestDelegate _next;
        public AutoTimerMiddleware(RequestDelegate next)
        {
            _next = next;
        }
        public async Task InvokeAsync(HttpContext httpContext)
        {


            var timer = new PeriodicTimer(TimeSpan.FromSeconds(5));

            int counter = 0;
            while (await timer.WaitForNextTickAsync())
            {
                counter++;
               // if (counter > 5) break;
                CallThisMethodEvery5Second(counter);
            }
            // Move forward into the pipeline
            await _next(httpContext);
        }
        public void CallThisMethodEvery5Second(int counter)
        {
            Console.WriteLine("Current counter: {0} Last Fired At: {1}", counter, DateTime.Now);
        }
    }

Примечание. При использовании в промежуточном программном обеспечении зарегистрируйтесь в файле program.cs следующим образом.

app.UseMiddleware<AutoTimerMiddleware>();

Вывод:

Реализация с использованием любого пользовательского класса/в любом месте:

            var timer = new PeriodicTimer(TimeSpan.FromSeconds(5));

            int counter = 0;
            while (await timer.WaitForNextTickAsync())
            {
                counter++;
                if (counter > 5) break;
                CallThisMethodEvery5Second(counter);
            }

Примечание. Вы будете вызывать свой метод GetCronExpression в пределах WaitForNextTickAsync, чтобы он вызывался в указанный вами период времени. Для демонстрации я вызываю это каждые 5 секунд.

Способ вызова:

public void CallThisMethodEvery5Second(int counter)
        {
            Console.WriteLine("Current counter: {0} Last Fired At: {1}",counter, DateTime.Now);
        }

Вывод:

Другие вопросы по теме