【发布时间】:2023-03-12 20:52:01
【问题描述】:
我正在尝试了解 MVC 的异步/等待机制。现在我不考虑退出“正常流程”(使用完全同步或完全异步端到端)的用例。我只是想确保了解它为什么在这里不起作用。
当调用“SyncMethod”时,它会无限期挂起并且永远不会返回。
当“AsyncMethod”被调用时,它会快速返回一个视图而不会挂起。
当“TaskMethod”被调用时,它会快速返回一个视图而不会挂起。
我不确定为什么当同步方法调用异步方法时不可能返回结果。
我在这里错过了什么?
using System;
using System.Threading.Tasks;
using System.Web.Mvc;
namespace MvcAsyncAwaitTest.Controllers
{
public class HomeController : Controller
{
/// <summary>
/// Synchronous method running async method as sync
/// Hangs at Hello().Result, never returns
/// </summary>
/// <returns></returns>
public ActionResult SyncMethod()
{
ViewBag.Message = Hello().Result;
return View();
}
/// <summary>
/// Asynchronous method awaiting asynchronous method
/// Do not hang
/// </summary>
/// <returns></returns>
public async Task<ActionResult> AsyncMethod()
{
ViewBag.Message = await Hello();
return View("Index");
}
/// <summary>
/// Synchronous method running a task based method synchronously
/// Returns a valid result
/// </summary>
/// <returns></returns>
public ActionResult TaskMethod()
{
ViewBag.Message = Hello2().Result;
return View("index");
}
private async Task<string> Hello()
{
return await HelloImpl();
}
private Task<string> Hello2()
{
return Task.Run(() => "Hello world 2");
}
private async Task<String> HelloImpl()
{
return await Task.Run(() => "Hello World");
}
}
}
【问题讨论】:
-
Stephen Cleary 在这里解释了异步/死锁困境:blog.stephencleary.com/2012/07/dont-block-on-async-code.html
-
Hello()的意义何在?它什么也没做。直接拨打HelloImpl即可。此外,创建一个方法async只是为了等待您返回的一项任务是没有意义的;只需使方法不是async并直接返回该任务。 -
@Servy 我可以做一个复杂的实现,但我更喜欢举一个非常简单的例子来准确理解这里的问题。但是,如果您想要一个更复杂的实现,请查看使用方式完全相同的 asp.net 身份框架。
-
@Erick 我在描述如何简化代码,而不是告诉你让它变得更复杂......
标签: c# async-await asp.net-mvc-5 asp.net-identity