15

I have an Index action in ASP.net MVC controller. This action, calls (among other things) a private action that do a count on a SQL table with large set of rows. The returned number will be inserted in a view bag property.

public ActionResult Index() { // do things ViewBag.NumberOfRows = NumberOfRows(); return View(); } private string NumberOfRows() { // sql connection and row count return numberOfRows; } 

This works but I can't see the Index page until everything is executed, even the row count. I would, instead, Index action to immediately complete, even if private function hasn't been completed yet. Than when count has been completed set a value to the view bag property. Right now I've done this:

private async Task<string> NumberOfRows() { SqlConnection connection = new SqlConnection(connString); SqlCommand cmd = new SqlCommand(); SqlDataReader reader; cmd.CommandText = "SELECT SUM (row_count) FROM sys.dm_db_partition_stats WHERE object_id=OBJECT_ID('aTable') AND (index_id=0 or index_id=1)"; cmd.CommandType = CommandType.Text; cmd.Connection = connection; await connection.OpenAsync(); reader = await cmd.ExecuteReaderAsync(); string numberOfRows = "N/A"; while (await reader.ReadAsync()) { numberOfRows = reader.GetInt64(0).ToString(); } connection.Close(); return numberOfRows ; } public async Task<ActionResult> Index(FormCollection form){ // do things; ViewBag.NumberOfRows = await NumberOfRows(); return View(); } 

This works. But is this really async? Am I miss something, there are other way of doing this?

1
  • 3
    Please note that SqlConnection, SqlCommand and SqlDataReader all implement the IDisposable interface, so you should consider using the using statement - this works well with async operations in it as well! Also see this question for more information: stackoverflow.com/q/16985876/927511 Commented Jul 6, 2015 at 11:39

3 Answers 3

16

It's an async call, but one important thing to understand here is, when you make your controller action async, the thread (of the asp.net thread pool), which handles the request, returns to the thread pool (the asp.net request thread pool).

This means it releases the thread of the thread pool to handle more requests, so the async controller action can handle more requests. It doesn't decrease the processing time, it just makes the server more responsive. Once async/await operation completes, the new thread from request thread pool does further processing.

If you want a real async page, i.e. you want to make your page more responsive, I suggest you make the call using the .ajax() function in jQuery or using the ajax extension available in Asp.net MVC.

Sign up to request clarification or add additional context in comments.

2 Comments

Ok perfect. But... at least is this the correct way of use async/await?
@marianoc84 - yes its correct way...first line of my answer tell that thing only...accept answer it it works for you
7

This works. But is this really async?

It is async in the fact that once you query your database (which is an IO bound operation), you free the ASP.NET Thread-Pool thread instead of using it to block until the query finishes.

Async doesn't mean "Return this request to the caller, and i'll finish executing at a later time", which is somewhat what you're expecting. It doesn't break the HTTP request-response protocol. What you want isn't achieved by async.

If you want the request to complete immediately, you'll need to queue it on some background thread, and push the data to the client side once the operation is complete.

Comments

2

Instead of async, use Task.Run:

Task.Run(() => MethodToExecuteInBackground(methodParameters)).ConfigureAwait(false).GetAwaiter(); 

You will also need to remove the async modifier from your controller Index method.

Now your controller method will return immediately while MethodToExecuteInBackground goes off and does some work in the background.

Be aware that this will tie up a thread-pool thread until MethodToExecuteInBackground finishes.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.