1

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?

Casey Crookston
  • 13,016
  • 24
  • 107
  • 193
  • 1
    Stop the timer, run the async task, add `ContinueWith` to the task to restart the timer? – DavidG Sep 01 '17 at 13:59
  • 1
    Don't use timer, rather single thread with loop with delay at the end of loop. – Sinatr Sep 01 '17 at 14:02
  • 1
    `var t = await ExecuteTransactionReportAsync();` ? You have to make the eventHandler async to use that. – Fildor Sep 01 '17 at 14:03
  • 1
    Little correction: Since it's `async Task ExecuteTransactionReportAsync` , that would have to be without `var t = ` just `await ExecuteTransactionReportAsync()` – Fildor Sep 01 '17 at 14:21
  • @Fildor, that was the first thing I tried. But then it forces the call in Start() to change to await as well, and I was having trouble getting that to work – Casey Crookston Sep 01 '17 at 14:43
  • @Fildor, as per your first comment, that's what I'm not sure how to do – Casey Crookston Sep 01 '17 at 14:43

1 Answers1

1

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(); });
}
Fildor
  • 14,510
  • 4
  • 35
  • 67
  • That works! I thought I had tried this, but I guess not. Thanks! – Casey Crookston Sep 01 '17 at 14:52
  • Ok, in my first comment when I said "that works" I was talking about your first example. Your second example is more what I was originally thinking about, or looking for. But I like your first example better. – Casey Crookston Sep 01 '17 at 14:54