remi bourgarel
remi bourgarel

Reputation: 9389

Why do you use async if you don't promote it to the controller?

I'm trying to figure out how to use async/await in C# in my Asp.Net MVC. The main point seems to be that it helps asp.net for releasing threads from the worker pool when you are doing IO (so they can process other stuff). For doing so you have to promote the async/await modifier from the method doing the IO call up to the controller action (you better have just a few layers).

Is there any point in using this feature without promoting the async/await up to my controller ? (by adding Task.Wait after a call to an Async method for instance).

Upvotes: 1

Views: 206

Answers (2)

Kasama Chenkhaow
Kasama Chenkhaow

Reputation: 54

The answer is "yes", but using Task.Wait() in an action is not a good idea because it can lead to a deadlock situation.

Consider the following from the guide, Async/Await Best Practice by Stephen Cleary:

Figure 3 A Common Deadlock Problem When Blocking on Async Code

public static class DeadlockDemo
{
   private static async Task DelayAsync()
   {
      await Task.Delay(1000);
   }
   // This method causes a deadlock when called in a GUI or ASP.NET context.
   public static void Test()
   {
       // Start the delay.
       var delayTask = DelayAsync();
       // Wait for the delay to complete.
       delayTask.Wait();
   }
}

However, if you add ConfigureAwait(false) to DelayAsync() like this:

await Task.Delay(1000).ConfigureAwait(false)

then you can avoid deadlocks, as explained in the article:

Aside from performance, ConfigureAwait has another important aspect: It can avoid deadlocks. Consider Figure 3 again; if you add “ConfigureAwait(false)” to the line of code in DelayAsync, then the deadlock is avoided. This time, when the await completes, it attempts to execute the remainder of the async method within the thread pool context. The method is able to complete, which completes its returned task, and there’s no deadlock. This technique is particularly useful if you need to gradually convert an application from synchronous to asynchronous.

Upvotes: 2

William Xifaras
William Xifaras

Reputation: 5312

Do not use Task.Wait as it can deadlock or produce an AggregateException. If you need to do this then you should use Task.WhenAll which is non-blocking.

Generally though, it is safest to use async code end-to-end. The benefit of using async away through the entire stack is that your code will be easier to debug and error handling much simpler.

So yes, if you are going to use async/await - include it in your controller and avoid using blocking code like Task.Wait.

Upvotes: 0

Related Questions