How to properly make asynchronous / parallel database calls How to properly make asynchronous / parallel database calls asp.net asp.net

How to properly make asynchronous / parallel database calls


Here is an example of how you would do it:

Here I am creating two methods to wrap two operations, you need to do the same for the other operations:

public async Task<int> MergeOneDataTableAsync(){    // Merge One procedure    using (SqlCommand cmd = new SqlCommand("MergeOneProcedure", dbc))    {        // 5 minute timeout on the query        cmd.CommandTimeout = 300;        cmd.CommandType = CommandType.StoredProcedure;        cmd.Parameters.AddWithValue("@TVP", MergeOneDataTable);        return await cmd.ExecuteNonQueryAsync().ConfigureAwait(false);    }}public async Task<int> MergeTwoDataTableAsync(){    // Merge Two procedure    using (SqlCommand cmd = new SqlCommand("MergeTwoProcedure", dbc))    {        // 5 minute timeout on the query        cmd.CommandTimeout = 300;        cmd.CommandType = CommandType.StoredProcedure;        cmd.Parameters.AddWithValue("@TVP", MergeTwoDataTable);        return await cmd.ExecuteNonQueryAsync().ConfigureAwait(false);    }}

Notice that I am using the ExecuteNonQueryAsync method to execute the query.

And then your original method would look like this:

using (var dbc = new SqlConnection(db.Database.Connection.ConnectionString)){    dbc.Open();    Task<int> task1 = MergeOneDataTableAsync();    Task<int> task2 = MergeTwoDataTableAsync();    Task.WaitAll(new Task[]{task1,task2}); //synchronously wait    recordedStatistics.Add("mergeOne", task1.Result);    recordedStatistics.Add("mergeTwo", task2.Result);}

Please note that I am keeping this method synchronous. Another option (actually a better one) is to convert the method into an asynchronous one like this:

public async Task<Dictionary<string, int>> MyOriginalMethod(){    //...    using (var dbc = new SqlConnection(db.Database.Connection.ConnectionString))    {        dbc.Open();        Task<int> task1 = MergeOneDataTableAsync();        Task<int> task2 = MergeTwoDataTableAsync();        int[] results = await Task.WhenAll(new Task<int>[]{task1,task2});        recordedStatistics.Add("mergeOne", results[0]);        recordedStatistics.Add("mergeTwo", results[1]);    }    //...    return recordedStatistics;}

But this would mean that you have to invoke it asynchronously (async all the way).