【发布时间】:2019-08-11 08:25:58
【问题描述】:
我尝试使用 Dapper 和存储过程并行执行三个类似的 SQL 查询,以便在所有查询完成后得到三个类似的结果。
这是我的代码:
public class SomeReport
{
private static readonly string ConnectionString = ConfigurationManager.ConnectionStrings["SomeContext"].ToString();
public ReportStatus ReportStatus { get; set; }
public long NetworkServerTime { get; set; }
public string ReportLastErrorMessage { get; set; }
public RowSet[] FirstRowSet { get; set; }
public RowSet[] SecondRowSet { get; set; }
public RowSet[] ThirdRowSet { get; set; }
public Report()
{
NetworkServerTime = 0;
ReportStatus = ReportStatus.NotCreated;
}
public async Task GetReportDataAsync(ReportParameters parameters)
{
DynamicParameters requestParameters = new DynamicParameters();
requestParameters.Add("@sinceDateFilter", parameters.SinceDate?.Date, DbType.DateTime);
requestParameters.Add("@untilDateFilter", parameters.UntilDate?.Date, DbType.DateTime);
requestParameters.Add("@countryId", parameters.CountryId, DbType.Int32);
ReportLastErrorMessage = null;
Task allTasks = null;
var stopWatch = new Stopwatch();
try
{
var firstTask = GetRows("[dbo].[GET_Report_FirstRowSet]", requestParameters);
var secondTask =
GetRows("[dbo].[GET_Report_SecondRowSet]", requestParameters);
var thirdTask =
GetRows("[dbo].[GET_Report_ThirdRowSet]", requestParameters);
allTasks = Task.WhenAll(firstTask, secondTask, thirdTask);
FirstRowSet = await firstTask;
SecondRowSet = await secondTask;
ThirdRowSet = await thirdTask;
}
catch (Exception ex)
{
ReportStatus = ReportStatus.Error;
ReportLastErrorMessage = allTasks?.Exception?.InnerExceptions.Last().Message;
}
finally
{
if (ReportStatus != ReportStatus.Error)
{
ReportStatus = ReportStatus.Success;
NetworkServerTime = stopWatch.ElapsedMilliseconds;
}
}
stopWatch.Reset();
}
private async Task<RowSet[]> GetRows(string procName, DynamicParameters parameters)
{
using (var conn = new SqlConnection(ConnectionString))
{
RowSet[] rowsSet;
try
{
var sqlString = string.Concat(procName, " @sinceDateFilter, @untilDateFilter, @countryId");
var query = await conn.QueryAsync<RowSet>(sqlString, parameters, commandTimeout: 500);
rowsSet = query.ToArray();
}
catch (SqlException sqlEx)
{
rowsSet = new RowSet[0];
throw;
}
return rowsSet;
}
}
}
但是当我启动调试器和 SQL Server Profiler 时,我看到查询是在创建对应的任务时按顺序执行的。
如何让查询同时开始运行并并行运行?
【问题讨论】:
-
你需要先
await allTasks,否则你实际上并没有使用Task.WhenAll -
对我来说,它看起来应该已经在做你想做的事了(除了上面的评论之外的小细节) - 是什么让你认为它们在这里实际上是连续的,而不是仅仅因为顺序被报告他们是如何开始的?另外:SqlClient 可能对这里的有效/无效有意见
-
@Marc 如果我使用调试器和 sql-profiler,我看到分析器中的第一个查询是在我在代码行
var firstTask = GetRows("[dbo].[GET_Report_FirstRowSet]", requestParameters);时执行的,但不是在我在代码行时代码allTasks = Task.WhenAll (firstTask, secondTask, thirdTask); -
嗨,为什么不用multiple query ?
标签: c# task-parallel-library dapper