亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

使用 Dapper 并行執行多個查詢

使用 Dapper 并行執行多個查詢

C#
HUX布斯 2023-08-20 15:28:59
我嘗試使用 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;        }但是,當我啟動調試器和 SQL Server Profiler 時,我發現在創建與其對應的任務時,查詢是按順序執行的。如何使查詢同時開始運行并并行運行?
查看完整描述

2 回答

?
慕碼人8056858

TA貢獻1803條經驗 獲得超6個贊

如果我使用調試器和 sql-profiler,我會看到探查器中的第一個查詢是在我位于代碼行時執行的,var firstTask = GetRows("[dbo].[GET_Report_FirstRowSet]", requestParameters);但不是在我位于代碼行時執行的allTasks = Task.WhenAll (firstTask, secondTask, thirdTask);

這是正確且正常的。async/ 的工作方式await是,一旦發生第一個不完整的await情況,控制權就會返回調用堆棧,在您的情況下是await conn.QueryAsync<RowSet>但是,您仍然只需通過調用 async 方法即可開始工作。該操作不會處于某種掛起狀態等待您調用Task.WhenAll,因此我們預計它已經開始。除了聚合等待Task.WhenAll步驟之外,不執行任何操作- 它在使事情實際發生方面沒有任何作用。

所以:我懷疑一切都已經按預期工作,但簡單地說:任務報告為按照您請求的順序開始。這正是我們所期望的。


查看完整回答
反對 回復 2023-08-20
?
胡說叔叔

TA貢獻1804條經驗 獲得超8個贊

因為所有任務都已在減速時間運行。當您從返回的 GetRow 方法分配任務時,您已經讓它開始了。然后使用 Task.WhenAll 創建一個新任務,當所有子任務完成時,該任務將返回已完成。但你也沒有等到這個任務。


這樣就保證了當三個任務完成時用await關鍵字執行完成。


如果您可以用一個單獨的任務包裝所有執行,您可以像這樣并行調用所有執行



var queries = new[] { 

    "[dbo].[GET_Report_FirstRowSet]", 

    "[dbo].[GET_Report_SecondRowSet]", 

    "[dbo].[GET_Report_ThirdRowSet]" 

};


var tasks = queries.Select(query => new Task(()=>{

    return GetRows(query, requestParameters);

})).ToArray();


Task.WaitAll(tasks);


查看完整回答
反對 回復 2023-08-20
  • 2 回答
  • 0 關注
  • 252 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號