桌面应用Async/Await改造后LINQ查询Task<List<Stocks>>报错求助
修正WinForm异步数据库查询的实现错误
你碰到的这个报错,核心问题是没正确处理异步方法的返回值——StockListAsync()返回的是Task<List<Stocks>>,这是一个待完成的任务对象,不是直接的股票列表集合。你直接拿Linq的Select去操作Task对象,自然找不到对应的方法,就会抛出那个错误啦。
下面咱们一步步修正这个问题:
1. 让GetStocks正确等待异步任务完成
把GetStocks改成异步方法,用await关键字获取StockListAsync()的实际结果,这样你拿到的才是真正的List<Stocks>,才能正常使用Linq或者遍历:
async void GetStocks() { // 用await等待异步方法执行完毕,拿到实际的股票列表 var stockList = await stock.StockListAsync(); // 如果不需要额外筛选,这里可以直接用stockList,不用Linq的Select var result = from stockItem in stockList select stockItem; GrdFood.Rows.Clear(); foreach (var item in result) { GrdFood.Rows.Add( GrdFood.RowCount + 1, item.Supplier, item.StockName, item.Description, item.Quantity.ToString("N2"), item.OrderQty.ToString("N2"), item.Cost.ToString("N2"), // 这里无需再转double,因为Cost已经是double类型 item.ID ); } }
2. 修改FormLoad事件,支持异步调用
WinForm的事件处理方法是少数允许使用async void的场景,咱们把FormLoad改成异步方法,然后awaitGetStocks():
private async void YourFormName_Load(object sender, EventArgs e) { await GetStocks(); }
(记得把YourFormName换成你实际的窗体类名)
3. 优化StockListAsync的资源管理(关键)
你的原始代码没有正确释放数据库连接、命令和阅读器,长期运行容易造成资源泄漏。咱们用using语句来自动释放这些实现了IDisposable接口的资源,保证代码的健壮性:
public async Task<List<Stocks>> StockListAsync() { List<Stocks> stocks = new List<Stocks>(); // using会自动在代码块结束时释放连接 using (var conn = await App_Code.DbConnection.InitializeConnectionAsync()) { string query = "SELECT * FROM tblStock"; // 用using包裹SqlCommand,自动释放 using (var cmd = new SqlCommand(query, conn)) { // 用using包裹SqlDataReader,自动释放 using (var reader = await cmd.ExecuteReaderAsync()) { if (reader.HasRows) { while (await reader.ReadAsync()) { var stockItem = new Stocks { ID = Convert.ToInt32(reader["ID"]), Supplier = Convert.ToInt32(reader["Supplier"]), StockCode = reader["StockCode"].ToString(), StockName = reader["StockName"].ToString(), Description = reader["Description"].ToString(), UnitMeasure = reader["Measurement"].ToString(), Quantity = Convert.ToInt32(reader["Quantity"]), OrderQty = Convert.ToInt32(reader["OrderQty"]), Cost = Convert.ToDouble(reader["Cost"]), }; stocks.Add(stockItem); } } } } } return stocks; }
这样修改后,你的异步代码就能正常运行,而且还解决了潜在的资源泄漏问题。
内容的提问来源于stack exchange,提问作者Austin Mrakpor
相关产品推荐
相关产品推荐

