我在WinForms应用程序中有一个数据访问层,该层访问SQL Server数据库。它包含几个DAO。在一种特定情况下,以下方法引发异常:“ BeginExecuteReader需要打开且可用的Connection。连接的当前状态为正在连接。”
public List<Product> readAllProducts()
{
List<Product> products = new List<Product>();
string queryGetAllProducts = "SELECT * FROM Products;";
using (SqlConnection conn = new SqlConnection(Configuration.CONNECTION_STRING))
{
SqlCommand cmd = new SqlCommand(queryGetAllProducts, conn);
try
{
conn.OpenAsync();
Task<SqlDataReader> readerTask = cmd.ExecuteReaderAsync();
SqlDataReader reader = readerTask.Result;
while (reader.Read())
{
// read the data...
}
}
catch (SqlException sqlEx)
{
throw;
}
finally
{
if (conn != null)
conn.Close();
}
}
}
在上面,我尝试将查询的执行结果包装在lock
语句中,但无济于事。这个想法是在完成数据库操作时有一个响应UI,对于此类中具有void
返回类型和async
-await
模式的其他方法,已经实现了这一点。当需要返回一个对象(或对象集合,如上例)时,如何实现并发?
但是它也必须等待(不是吗?),依此类推
是的,就是那个; await
具有传染性。因此,您最终会得到:
public async Task<List<Product>> ReadAllProducts()
{
List<Product> products = new List<Product>();
string queryGetAllProducts = "SELECT * FROM Products;";
using (SqlConnection conn = new SqlConnection(Configuration.CONNECTION_STRING))
{
// ...
}
}
但要注意,这里的lot更多操作与async
兼容-例如ReadAsync
等。或者简单起见,只需让Dapper做繁重的工作即可:
public async Task<List<Product>> ReadAllProducts()
{
using (var conn = new SqlConnection(Configuration.CONNECTION_STRING))
{
var products = await conn.QueryAsync<Product>("SELECT * FROM Products;");
return products.AsList();
}
}
然后您的呼叫用法将await
此:
var data = await ReadAllProducts();
// do something with "data"