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配置文件也没有抛出异常.所以当我在第一个例子中挂起时,我不知道发生了什么.
我假设您的第一个示例正在使用Result,从而导致我在博客上解释的死锁.
总之,ASP.NET提供了一个"请求上下文",它一次只允许一个线程.当您使用阻塞线程时Result,该线程被锁定到该上下文中.稍后,当FindByIdAsync尝试在该上下文中恢复时,它不能,因为已经有另一个线程已被阻塞.