简体   繁体   中英

Async method lacks await operators warning when the await is in a function passed to an async lambda expresion

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?

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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM