How to properly make asynchronous / parallel database calls

后端 未结 1 371
无人及你
无人及你 2020-12-14 06:51

I\'m looking for the proper way to handle multiple database calls that would likely benefit from running simultaneously. The queries are just to stored procedures that are

相关标签:
1条回答
  • 2020-12-14 07:52

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

    0 讨论(0)
提交回复
热议问题