What is the best practice to fill a DataSet or DataTable asynchronously in ASP.NET?

Adrian Anttila picture Adrian Anttila · Aug 29, 2014 · Viewed 8.8k times · Source

Given the following code, I have a few questions about best practices:

string connectionString = @"Server=(local)\sqlexpress; Database=master; Integrated Security=true;";

using (SqlConnection connection = new SqlConnection(connectionString))
{
    using (SqlDataAdapter dataAdapter = new SqlDataAdapter("select * from information_schema.columns", connection))
    {
        await connection.OpenAsync();

        DataTable dataTable = new DataTable();
        await Task.Run(() => dataAdapter.Fill(dataTable));
        return dataTable;
    }
}

I've seen several examples that wrap the whole block of code in a Task.Run() call, but I'm not sure if that's better than calling Task.Run() only for the DataAdapter.Fill() method, which feels more flexible and specific (only using await on async tasks).

Is the approach of calling Task.Run() on the Fill() method better than wrapping the whole code block?

Are there any negative side-effects to calling Fill() in Task.Run()? I'm thinking of something along the lines of losing call stack and/or exception information if Fill() has an error.

Is there a better way to write this in ASP.NET?

Answer

usr picture usr · Aug 29, 2014

In ASP.NET it almost never helps to use Task.Run. What exactly would it improve? It only introduces overhead.

That said, Fill will perform IO (draining the data reader) so you might want to call it asynchronously. Unfortunately, there is no async version of this method.

If you insist on using async IO (which is questionable for database access) you need to find an alternative. Maybe async Entity Framework or raw ADO.NET can help you.