0

I have the following async method, which is a simpler wait and retry in case of failures:

public async Task RetryAsync(Func<Task> _action, int _ms = 1000, int _counter = 3) {
    while (true) {
        try {
            await _action();
            return; // success!
        }
        catch {
            if (--_counter == 0)
                throw;
            await Task.Delay(_ms);
        }
    }
}

To, in theory, be called like this:

await RetryAsync(async () => {
    _newID = myDBFunction();
}, 300);

Since the function passed to the RetryAsync method does not contain any await, then obviously this gets the warning:

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

... and changing the calling code to this fixes the problem:

await RetryAsync(async () => {
    await Task.Run(() => _newID = myDBFunction(););
}, 300);

Is there any other way to achieve parallelism for this simple case besides using Task.Run()? Any disadvantage you see to the latest code with Task.Run() on it?

Miguel Mateo
  • 189
  • 1
  • 15

1 Answers1

2

First, I recommend using Polly. It's widely used, extensively tested, and has native support for asynchronous as well as synchronous usage.

But if you want to keep using your own, you can add a synchronous equivalent:

public async Task RetryAsync(Func<Task> _action, int _ms = 1000, int _counter = 3);
public void Retry(Action _action, int _ms = 1000, int _counter = 3);

which can be called as such:

Retry(() => {
  _newID = myDBFunction();
}, 300);

If you want to always put synchronous code on a thread pool, you can add an overload for that, to:

public async Task RetryAsync(Func<Task> _action, int _ms = 1000, int _counter = 3);
public async Task RetryAsync(Action _action, int _ms = 1000, int _counter = 3) =>
    await RetryAsync(() => Task.Run(_action), _ms, _counter);

which can be called as such:

await RetryAsync(() => {
    _newID = myDBFunction();
}, 300);
Miguel Mateo
  • 189
  • 1
  • 15
Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810