异步 SqlConnection - return 除了任务之外的东西
Asynchronous SqlConnection - return something other than a Task
我在 WinForms 应用程序中有一个数据访问层,它查询 SQL 服务器数据库。它包含几个 DAO。在一种特殊情况下,以下方法会引发异常:"BeginExecuteReader requires an open and available Connection. The connection's current state is connecting."
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 ,这已经为这个 class 中的其他方法实现了一些 void
return 类型,与async
-await
模式。当需要 return 一个对象(或对象集合,如上例)时,如何实现并发?
but it would have to await that as well (wouldn't it?), and so on up the chain
是的,正是这样; 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))
{
// ...
}
}
但请注意,这里有更多 很多 操作是 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"
我在 WinForms 应用程序中有一个数据访问层,它查询 SQL 服务器数据库。它包含几个 DAO。在一种特殊情况下,以下方法会引发异常:"BeginExecuteReader requires an open and available Connection. The connection's current state is connecting."
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 ,这已经为这个 class 中的其他方法实现了一些 void
return 类型,与async
-await
模式。当需要 return 一个对象(或对象集合,如上例)时,如何实现并发?
but it would have to await that as well (wouldn't it?), and so on up the chain
是的,正是这样; 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))
{
// ...
}
}
但请注意,这里有更多 很多 操作是 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"