如何在C#异步方法中将列表返回给调用方?
如何在异步函数中返回列表给调用方
我来帮你搞定这个问题~你的代码里有几个关键问题需要调整,才能正确地从异步函数返回列表,下面一步步给你说明:
原代码的核心问题
- 使用了
async void:这种写法主要是给事件处理器用的,普通异步方法用它无法获取返回值,也很难正确处理异常。 - 静态列表
ResultList存在风险:静态列表会在多次调用间共享状态,而且异步操作中多线程访问容易出现线程安全问题,还可能导致数据混乱。 - 方法设计没有返回值逻辑:你的
callSpForTS方法没有返回结果的设计,调用方自然拿不到列表。
修改后的完整实现
首先修正类型不一致的问题(原代码里列表是List<Data>但添加的是ResultData,这里统一成ResultData),然后调整异步方法的写法:
public class ResultData { public int Status { get; set; } public string Description { get; set; } public int BatchId { get; set; } } // 把异步方法改成返回Task<List<ResultData>>,这样调用方可以await获取结果 public static async Task<List<ResultData>> CallSpForTS(int piGroupId, int piIssuerId, DateTime pdFromDate, DateTime ldToDate, int piFormulaId, int piIsProcessedType, int piIsSeriesReStart, int piIsPLCalculate, int piIsIncludeEditedScoreint) { // 每次调用创建新列表,避免状态共享和线程安全问题 var resultList = new List<ResultData>(); try { // 建议用using语句确保数据库资源正确释放,这里假设你已经有可用的数据库连接 using (var sqlCommand = new SqlCommand("你的存储过程名称", 你的数据库连接对象)) { // 记得添加存储过程需要的参数 // sqlCommand.Parameters.AddWithValue("@ParamName", paramValue); // 如果数据库驱动支持异步,优先用原生异步方法,比Task.Run更高效 await sqlCommand.ExecuteNonQueryAsync(); var item = new ResultData(); item.Description = "successful"; item.Status = 1; item.BatchId = 100; resultList.Add(item); } } catch (Exception ex) { Common.showMessageBox($"{ex.Message} InnerException: {ex.InnerException}", MSG_TYP.Error, "Error Occured"); // 可以把错误信息也加入结果列表,方便调用方知晓异常情况 resultList.Add(new ResultData { Status = 0, Description = $"执行出错: {ex.Message}" }); } return resultList; } // 调用异步方法的方法也要改成async,并用await获取结果 public async Task<List<ResultData>> TSReCalculation(int piGroupId, int piIssuerId, DateTime pdFromDate, DateTime ldToDate, int piFormulaId, int piIsProcessedType, int piIsSeriesReStart, int piIsPLCalculate, int piIsIncludeEditedScoreint) { // await异步方法,拿到返回的列表 return await CallSpForTS(piGroupId, piIssuerId, pdFromDate, ldToDate, piFormulaId, piIsProcessedType, piIsSeriesReStart, piIsPLCalculate, piIsIncludeEditedScoreint); }
关键知识点说明
async Task<T>的作用:这是异步方法返回值的标准写法,Task<T>代表一个会返回T类型结果的异步操作,调用方通过await可以等待操作完成并获取结果。- 线程安全的列表使用:每次调用异步方法都创建新的
List<ResultData>,避免了多线程同时修改同一个静态列表的风险,也不会保留上一次调用的旧数据。 - 异步数据库操作优化:如果你的数据库操作支持异步(比如SqlClient的
ExecuteNonQueryAsync),直接用await调用这些方法,比把同步操作包在Task.Run里更高效,不会浪费线程池资源。
内容的提问来源于stack exchange,提问作者Ajay Nirmal
相关产品推荐
相关产品推荐

