我正在寻找处理多个数据库调用的适当方法,这些方法可能会受益于同时运行。这些查询仅针对存储过程,这些存储过程使用在ASP.NET MVC应用程序中以编程方式组装到DataTables中的数据进行插入或合并。
当然,我已经看到了有关async
和await
的一些信息,这似乎是我需要做的,但是我对如何实现它没有清晰的了解。一些信息表明,这些调用仍将是顺序的,并且一个仍将等待另一个完成。这似乎毫无意义。
最终,我希望有一个解决方案,使我可以在花费最长的时间才能完成的时间内运行所有查询。我希望所有查询也返回受影响的记录数(就像现在一样)。
这是我现在正在做的(绝不是并行的):
// Variable for number of records affected
var recordedStatistics = new Dictionary<string, int>();
// Connect to the database and run the update procedure
using (var dbc = new SqlConnection(db.Database.Connection.ConnectionString))
{
dbc.Open();
// 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);
// Execute procedure and record the number of affected rows
recordedStatistics.Add("mergeOne", cmd.ExecuteNonQuery());
}
// 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);
// Execute procedure and record the number of affected rows
recordedStatistics.Add("mergeTwo", cmd.ExecuteNonQuery());
}
// Merge Three procedure
using (SqlCommand cmd = new SqlCommand("MergeThreeProcedure", dbc))
{
// 5 minute timeout on the query
cmd.CommandTimeout = 300;
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@TVP", MergeThreeDataTable);
// Execute procedure and record the number of affected rows
recordedStatistics.Add("mergeThree", cmd.ExecuteNonQuery());
}
// Merge Four procedure
using (SqlCommand cmd = new SqlCommand("MergeFourProcedure", dbc))
{
// 5 minute timeout on the query
cmd.CommandTimeout = 300;
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@TVP", MergeFourDataTable);
// Execute procedure and record the number of affected rows
recordedStatistics.Add("mergeFour", cmd.ExecuteNonQuery());
}
// Merge Five procedure
using (SqlCommand cmd = new SqlCommand("MergeFiveProcedure", dbc))
{
// 5 minute timeout on the query
cmd.CommandTimeout = 300;
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@TVP", MergeFiveDataTable);
// Execute procedure and record the number of affected rows
recordedStatistics.Add("mergeFive", cmd.ExecuteNonQuery());
}
dbc.Close();
}
return recordedStatistics;
所有这些代码都在为DataTables组装数据的同一方法内。我对async
的有限理解使我相信我需要将前面的代码提取到自己的方法中。然后,我将调用该方法并返回await
。但是,我什至不了解它。
我以前从未做过任何异步/并行/多线程编码。这种情况使我觉得现在是进入的最佳时机。也就是说,我想学习最好的方法,而不必学习错误的方法。
参考方案
这是您将如何做的一个例子:
在这里,我正在创建两个包装两个操作的方法,您需要对其他操作做同样的事情:
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);
}
}
请注意,我正在使用ExecuteNonQueryAsync
方法执行查询。
然后您的原始方法将如下所示:
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);
}
请注意,我正在使此方法保持同步。另一种选择(实际上是更好的选择)是将方法转换为异步方法,如下所示:
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;
}
但这意味着您必须异步调用它(async all the way)。
当回复有时是一个对象有时是一个数组时,如何在使用改造时解析JSON回复? - java我正在使用Retrofit来获取JSON答复。这是我实施的一部分-@GET("/api/report/list") Observable<Bills> listBill(@Query("employee_id") String employeeID); 而条例草案类是-public static class…
改造正在返回一个空的响应主体 - java我正在尝试使用Retrofit和Gson解析一些JSON。但是,我得到的响应机构是空的。当我尝试从对象中打印信息时,出现NullPointerException。我确保URL正确,并且我也确保POJO也正确。我正在使用jsonschema2pojo来帮助创建POJO类。这是我要解析的JSON{ "?xml": { "@versi…
每个文件合并后添加换行 - python我有很多类似以下内容的JSON文件:例如。1.json{"name": "one", "description": "testDescription...", "comment": ""} test.json{"name"…
Json到php,json_decode返回NULL - php我正在用PHP进行JSON解析器的一些API,用于存储有关遗产的信息。我在解析时遇到问题,因为它返回的是NULL值而不是数组或对象。简单的JSON代码可以很好地解析,但是可以这样:{"success":true,"totalCount":1,"data":[{"id":99694…
将ajax的值存储到javascript变量中 - javascript我有一个php文件,其中我从服务器获取数据。该php文件的输出是一个包含json格式数据的变量。PHP文件:<?php $dbHostName = "localhost"; $dbUserName = "venseld"; $dbUserPass = "wecuuu"; $dbName = &…