3

I tried to make an async database call to SQL Server and use it along with new ASP.NET MVC 4 async features but it strangely does not return at all. I debugged the code, works nicely but somehow the HTTP request hangs open forever.

Here is what I did:

This is the database call method:

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();
            }
        }
    }
}

Here, Select method on SqlDataReader is an extension method which I implemented. carBuilder private method just returns back an instance of Car class.

This is the controller class:

public class HomeController : Controller {

    private readonly GalleryContext ctx = new GalleryContext();

    public async Task<ViewResult> IndexAsync() {

        return View("Index", await ctx.GetCarsAsync());
    }
}

Any idea what I am missing?

2

2 Answers 2

3

Your controller still needs to derive from AsyncController (see Exercise 4: Using Asynchronous Controllers), but now you need to write less code to achieve the same result with Task<T>.

So this should work:

public class HomeController : AsyncController {

    private readonly GalleryContext ctx = new GalleryContext();

    public async Task<ViewResult> IndexAsync() {

        return View("Index", await ctx.GetCarsAsync());
    }
}
Sign up to request clarification or add additional context in comments.

4 Comments

I don't think it has to. I have several other Task-based async actions which consumes web services asynchronously and the controller for those derived from Controller class. Let me try, though.
ah, bummer! It worked but it is strange because as I said, I have several other Task-based async actions which consumes web services asynchronously and the controller for those derived from Controller class.
I don't know what is causing the difference... but according to the sample and the other articles online, you should derive from AsyncController.
Hi, please see the @marcind's answer. That is the solution.
2

There is a bug in MVC 4 Beta that causes a hang when you return an async Task that completes really quickly.

The workaround to it is to add the following as the first line of your action method:

await Task.Yield();

Could you see if that fixes it?

More info here: http://aspnetwebstack.codeplex.com/workitem/22

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.