Should I use await with async Action method?

To write non-blocking asynchronous code, you need to execute some kind of existing non-blocking asynchronous operation, such as Task.Delay(), or async network or file IO.

In short, the await keyword consumes asynchrony; it does not create it.

If you don't have any actual asynchronous work to do, await won't do you any good.


I need to implement an asynch Action in my Controller for a long running external API call.
...
My question is, is this enough to make is truly non-block asynchronous? Do I also need to apply the await operator, and if so how should I do that?

The C# compiler is probably already suggesting the async keyword is redundant here:

[AsyncTimeout(200)]
public async Task<ActionResult> DoAsync()
{
    // Execute long running call.
    return View();
}

The fact that you've added the async keyword doesn't make your method magically run in the background.

If you do something like await Task.Run(() => View()) as suggested by another answer, you still won't break through the boundaries of a given HTTP request. The request processing will take at least as much time to generate the View as without Task.Run. The client-side browser will still be waiting for it.

This pattern is good for a UI app, when you need to offload a CPU-bound work to a pool thread, to avoid blocking the UI thread and keep the UI responsive. However, using it within an HTTP request handler inside an ASP.NET app is almost never a good idea. It will only hurt the performance and scalability.

One solution, providing a user-friendly experience for when the View takes significant amount of time to compose, is to run a background task which spans the boundary of a single HTTP requests. Then further use AJAX requests to keep the client-side browser updated with the progress. Here's a great example by Alan D. Jackson, doing just that:

Long Running Background Tasks in Asp.Net MVC3.

However, running a lengthy background operation across multiple HTTP requests inside the same ASP.NET server process is not a very good idea. While it's relatively easy to implement, this approach may create issues with IIS maintainability, scalability and security.

You might be better off with a separate Windows/WCF service for that, which would expose a Task-based API. Then use AJAX to periodically poll the WCF service, using a dedicated method of your ASP.NET MVC controller as a proxy for the polling call.