Casey Crookston
Casey Crookston

Reputation: 13955

Prevent a timer from restarting until it's async task is done

I thought at first this was going to be just a "How to wait for async method to complete?" question. But, I think it's a little more than that.

I have a timer set up as such...

public void Start()
{
    _timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
    _timer.Interval = _context.adpSettings.SyncInterval * 1000;
    _timer.AutoReset = false;
    _timer.Enabled = true;
}

private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    var t = ExecuteTransactionReportAsync();
    _timer.Start(); 
}

private async Task ExecuteTransactionReportAsync()
{
    AccessEvent accessEvent = new AccessEvent();
    ....  do some logic
    await _context.GetConnector().EnqeueuEventAsync(accessEvent);
}

What I'm trying to do is to NOT have timer_Elapsed() fire again until after ExecuteTransactionReportAsync() is done. But, because ExecuteTransactionReportAsync() is async, the process keeps going and timer_Elapsed() will fire again.

In real life, it will never take ExecuteTransactionReportAsync() more than 10 seconds to finish it's task. (At least it better not or we have other problems.) But when I'm debugging, it's a pain.

Is there a simple solution that doesn't involve making ExecuteTransactionReportAsync() non async?

Upvotes: 1

Views: 920

Answers (1)

Fildor
Fildor

Reputation: 16129

If my understanding of TAP is correct, then this should work as intended:

private async void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    await ExecuteTransactionReportAsync();
    _timer.Start(); 
}

Or what DavidG was suggesting:

private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    _timer.Stop();
    ExecuteTransactionReportAsync().ContinueWith( () => {_timer.Start(); });
}

Upvotes: 1

Related Questions