1

This is my code in .net core 5 which wants to trigger a function every 2 minutes. I don't know why LoadData function doesn't get triggered after 2 minutes and only get triggered the first time?

public Task StartAsync(CancellationToken stoppingToken)
{
    var _timer = new System.Threading.Timer(LoadData, null, TimeSpan.Zero, TimeSpan.FromMinutes(2));

    return Task.CompletedTask;
}

private async void LoadData(object state)
{
   var res = await _repository.GetAsync();
   //....
}
Nega
  • 119
  • 8
  • 3
    The timer is no longer in scope. You should make it a field and dispose it manually. ... Or just use `BackgroundService` and a `while{ await Task.Delay()...}` loop... – Jeremy Lakeman Aug 15 '23 at 11:20
  • 1
    More specifically, since it is not in scope (for all running code), it may be eligible for garbage collection, which will stop the timer. – Stephen Cleary Aug 15 '23 at 11:57
  • 1
    create `_timer` field and remove `var` from `var _timer = ...` – Guru Stron Aug 15 '23 at 12:07

1 Answers1

3

The following line:

var _timer = new System.Threading.Timer(LoadData, null, TimeSpan.Zero, TimeSpan.FromMinutes(2));

Will create a timer and save the reference only to local variable, allowing the GC to collect the System.Threading.Timer. Workaround can be to introduce a field:

System.Threading.Timer _timer;

public Task StartAsync(CancellationToken stoppingToken)
{
    _timer = new System.Threading.Timer(LoadData, null, TimeSpan.Zero, TimeSpan.FromMinutes(2));

    return Task.CompletedTask;
}

Also switching to System.Timers.Timer could also work (but have not tested it).

See also:

Guru Stron
  • 102,774
  • 10
  • 95
  • 132