2

I had the following action which hung and never returned:

public Task<ActionResult> ManageProfile(ManageProfileMessageId? message)
        {
            ViewBag.StatusMessage =
                message == ManageProfileMessageId.ChangeProfileSuccess
                    ? "Your profile has been updated."
                                : message == ManageProfileMessageId.Error
                                      ? "An error has occurred."
                                      : "";
            ViewBag.ReturnUrl = Url.Action("ManageProfile");

            var user = UserManager.FindByIdAsync(User.Identity.GetUserId());
            var profileModel = new UserProfileViewModel
            {
                Email = user.Email,
                City = user.City,
                Country = user.Country
            };

            return View(profileModel);
        }

but when I converted it to this:

 public async Task<ActionResult> ManageProfile(ManageProfileMessageId? message)
        {
            ViewBag.StatusMessage =
                message == ManageProfileMessageId.ChangeProfileSuccess
                    ? "Your profile has been updated."
                                : message == ManageProfileMessageId.Error
                                      ? "An error has occurred."
                                      : "";
            ViewBag.ReturnUrl = Url.Action("ManageProfile");

            var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
            var profileModel = new UserProfileViewModel
            {
                Email = user.Email,
                City = user.City,
                Country = user.Country
            };

            return View(profileModel);
        }

It returned right away. So Im not sure what is going on with this? If its as simple as the method returned without waiting on the result of FindByIdAsync, then why didn't I get a view with nothing in it.

So it appears to me that it neither waited for the return of:

UserManager.FindByIdAsync(User.Identity.GetUserId());

nor returned a null profile nor threw an exception. So I dont get whats happening here when it's hanging in the first example.

2
  • 2
    Your first code snippet does not compile. Commented Oct 30, 2013 at 22:47
  • There is no error in your 2nd code snippet, the problem is most likely with the UserManager.FindByIdAsync method which we do not have the code for. If I were to guess I would say it's not starting the Task that it returns so that task is be waited on indefinitely. As a matter of convention an async method should always start the Task it returns. Commented Oct 30, 2013 at 22:51

1 Answer 1

9

I assume your first example was using Result, thus causing a deadlock that I explain on my blog.

In summary, ASP.NET provides a "request context" which only allows one thread in at a time. When you block a thread using Result, that thread is locked into that context. Later, when FindByIdAsync attempts to resume on that context, it cannot because there's another thread already blocked in it.

Sign up to request clarification or add additional context in comments.

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.