1、有时候我们需要同时执行一些操作,然后把这些操作的结果进行汇总,以达到用异步处理降低操作耗时的效果,此时我们会考虑使用Task,而Task.WhenAll则排上了用场。
public void IssueStatistics(Msg msg) { string guid = Util.GetGuid(); try { var beginTime = msg.ToString(0); var endTime = msg.ToString(1); var task = GetIssueStatisticsAsync(beginTime, endTime); var dtRet = task.Result; } }
private async Task<DataTable> GetIssueStatisticsAsync(string beginTime, string endTime) { var taskList = new List<Task<DataTable>> { GetIssueDataAsync(beginTime, endTime), GetB2CIssueDataAsync(beginTime, endTime) }; var tasks = taskList.ToArray(); var tables = await Task.WhenAll(tasks).ConfigureAwait(false); var retDt = orderDAL.CreateIssueDataTable(); for (int index = 0; index < tables.Length; index++) { for (int k = 0; k < tables[index].Rows.Count; k++) { retDt.ImportRow(tables[index].Rows[k]); } } return retDt; } private Task<DataTable> GetIssueDataAsync(string beginTime, string endTime) { return Task.Run(() => { var dt = orderDAL.GetIssueDataOfOrder(beginTime, endTime); return dt; }); } private Task<DataTable> GetB2CIssueDataAsync(string beginTime, string endTime) { return Task.Run(() => { var dt = orderDAL.GetIssueDataOfB2C(beginTime, endTime); return dt; }); }
这里有个地方需要注意的,如果不是在控制台应用程序,那么需要在Task.WhenAll后面加 ConfigureAwait(false),不然无法返回当前线程。
当然,按照官网的实例写法,你也可以这样写:
private async Task<int> ExecuteDataAsync(bool isJit, int topRows, bool isRetry) { var dtRecord = _dao.GetDataOfStockOut(topRows, isRetry); var dataList = _comDao.ToSyncDataList(dtRecord); if (dataList == null) return 0; var tasksQuery = from data in dataList select DoRunIssueDataAsync(data); var tasks = tasksQuery.ToArray(); int[] flags = await Task.WhenAll(tasks); int total = flags.Sum(); return total; } private async Task<int> DoRunIssueDataAsync(SyncDataM data) { return await Task.Run(() => { //要处理的事情return 1; }); }
这样调用就可以了:
var task = ExecuteDataAsync(true, 20, true); task.Wait();