vs-threading icon indicating copy to clipboard operation
vs-threading copied to clipboard

Analyzer proposal: remove redundant state machine

Open AArnott opened this issue 6 years ago • 5 comments

Call out where an async state machine is redundant:

async Task<string> DoSomethingAsync()
{
   return await SomethingElseAsync(); // .ConfigureAwait(bool) might be a suffix
}

So long as SomethingElseAsync() returns the same type as the caller, you can abbreviate to:

Task<string> DoSomethingAsync()
{
   return SomethingElseAsync();
}

This is almost equivalent, but it doesn't guarantee exceptions are caught and returned as exceptions, so strictly speaking this is more equivalent:

Task<string> DoSomethingAsync()
{
   try
   {
      return SomethingElseAsync();
   }
   catch (Exception ex)
   {
      return Task.FromException(ex);
   }
}

Cases that cannot be simplified include;

  1. more than one await
  2. The await is not immediately returned (or not the last statement).
  3. The await appears inside a try block.
  4. A using var appears in the method, such that it will be disposed of prior to the returned Task being completed.

AArnott avatar Sep 17 '19 19:09 AArnott

Probably should offer 2 code fixes, with an additional comment around the try-catch for the more complex code fix?

mavasani avatar Sep 17 '19 19:09 mavasani

I generally make this change manually and would appreciate the analyzer, but we should be aware that it changes the debugging experience by removing DoSomethingAsync from the call stack when the program is executing a continuation in SomethingElseAsync.

drewnoakes avatar Sep 17 '19 23:09 drewnoakes

Removing async also disables the compiler warning saying a task should be awaited, so you'll definitely want to make sure that analyzer is working well before suggesting that async get removed.

sharwell avatar Nov 23 '19 02:11 sharwell

This is a performance optimization but it causes a change in the stack trace if an exception is thrown.

Check this post from @StephenCleary:

Eliding Async and Await

paulomorgado avatar Dec 02 '19 21:12 paulomorgado

ReSharper extensiosn ReCommended Extension and AsyncConverter suggesting to remove async/await. This is indeed changes the stack trace but it is still a useful analysis.

NN--- avatar Sep 30 '20 10:09 NN---