ASP.NET MVC 4异步数据库调用:从不返回HTTP响应

时间:2012-04-02 21:01:59

标签: asp.net sql-server asp.net-mvc asp.net-mvc-4 async-await

我尝试对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());
    }
}

知道我缺少什么吗?

2 个答案:

答案 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();

你能看到是否修复了它?

此处有更多信息:http://aspnetwebstack.codeplex.com/workitem/22