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?
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.