我尝试对SQL Server进行异步数据库调用,并将其与新的ASP.NET MVC 4异步功能一起使用,但奇怪的是根本没有返回。我调试了代码,运行良好,但不知何故HTTP请求永远挂起。
这是我做的:
这是数据库调用方法:
public async Task<IEnumerable<Car>> GetCarsAsync() {
var connectionString = ConfigurationManager.ConnectionStrings["CarGalleryConnStr"].ConnectionString;
var asyncConnectionString = new SqlConnectionStringBuilder(connectionString) {
AsynchronousProcessing = true
}.ToString();
using (var conn = new SqlConnection(asyncConnectionString)) {
using (var cmd = new SqlCommand()) {
cmd.Connection = conn;
cmd.CommandText = selectStatement;
cmd.CommandType = CommandType.Text;
conn.Open();
using (var reader = await cmd.ExecuteReaderAsync()) {
return reader.Select(r => carBuilder(r)).ToList();
}
}
}
}
此处,Select
上的SqlDataReader
方法是我实施的扩展方法。 carBuilder
私有方法只返回Car
类的实例。
这是控制器类:
public class HomeController : Controller {
private readonly GalleryContext ctx = new GalleryContext();
public async Task<ViewResult> IndexAsync() {
return View("Index", await ctx.GetCarsAsync());
}
}
知道我缺少什么吗?
答案 0 :(得分:3)
您的控制器仍然需要从AsyncController派生(请参阅Exercise 4: Using Asynchronous Controllers),但现在您需要编写更少的代码才能获得与Task<T>
相同的结果。
所以这应该有效:
public class HomeController : AsyncController {
private readonly GalleryContext ctx = new GalleryContext();
public async Task<ViewResult> IndexAsync() {
return View("Index", await ctx.GetCarsAsync());
}
}
答案 1 :(得分:2)
MVC 4 Beta中存在一个错误,当您返回非常快速完成的异步Task
时会导致挂起。
解决方法是将以下内容添加为操作方法的第一行:
await Task.Yield();
你能看到是否修复了它?