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