在ASP.Net MVC中使用async

ris*_*ism 2 c# asp.net-mvc async-await

我有以下行动,挂起并且从未返回:

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);
        }
Run Code Online (Sandbox Code Playgroud)

但当我把它转换成这个时:

 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);
        }
Run Code Online (Sandbox Code Playgroud)

它马上就回来了.所以我不确定这是怎么回事?如果它像返回的方法一样简单而不等待FindByIdAsync的结果,那么为什么我没有得到任何内容的视图.

所以在我看来,它既没有等待返回:

UserManager.FindByIdAsync(User.Identity.GetUserId());
Run Code Online (Sandbox Code Playgroud)

也没有返回null配置文件也没有抛出异常.所以当我在第一个例子中挂起时,我不知道发生了什么.

Ste*_*ary 9

我假设您的第一个示例正在使用Result,从而导致我在博客上解释的死锁.

总之,ASP.NET提供了一个"请求上下文",它一次只允许一个线程.当您使用阻塞线程时Result,该线程被锁定到该上下文中.稍后,当FindByIdAsync尝试在该上下文中恢复时,它不能,因为已经有另一个线程已被阻塞.