ChatGPT解决这个技术问题 Extra ChatGPT

将异步与 MVC5 一起使用有什么好处?

有什么区别:

public ActionResult Login(LoginViewModel model, string returnUrl)
{
    if (ModelState.IsValid)
    {
        IdentityResult result = IdentityManager.Authentication.CheckPasswordAndSignIn(AuthenticationManager, model.UserName, model.Password, model.RememberMe);
        if (result.Success)
        {
            return Redirect("~/home");
        }
        else
        {
            AddErrors(result);
        }
    }
    return View(model);
}

和:

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
    if (ModelState.IsValid)
    {
        IdentityResult result = await IdentityManager.Authentication.CheckPasswordAndSignInAsync(AuthenticationManager, model.UserName, model.Password, model.RememberMe);
        if (result.Success)
        {
            return Redirect("~/home");
        }
        else
        {
            AddErrors(result);
        }
    }
    return View(model);
}

我看到 MVC 代码现在有异步但有什么区别。一个提供比另一个更好的性能吗?调试一个问题比另一个更容易吗?我应该对其他控制器进行更改以使我的应用程序添加 Async 吗?

在绝大多数情况下,在 MVC 中使用异步并没有什么好处,但是也有很多负面影响
@ChrisMarisic - 最严重的问题之一:您不能使用 ReaderWriterLock 或任何其他同步原语(信号量除外)。

D
Darin Dimitrov

仅当您执行 I/O 绑定操作(例如远程服务器调用)时,异步操作才有用。异步调用的好处是在 I/O 操作期间,不使用 ASP.NET 工作线程。下面是第一个示例的工作原理:

当请求命中操作时,ASP.NET 从线程池中获取一个线程并开始执行它。调用 IdentityManager.Authentication.CheckPasswordAndSignIn 方法。这是一个阻塞调用 -> 在整个调用期间,工作线程受到威胁。

以下是第二个调用的工作方式:

当请求命中操作时,ASP.NET 从线程池中获取一个线程并开始执行它。调用 IdentityManager.Authentication.CheckPasswordAndSignInAsync 并立即返回。注册 I/O 完成端口并将 ASP.NET 工作线程释放到线程池。稍后当操作完成时,发出 I/O 完成端口信号,从线程池中提取另一个线程以完成返回视图。

正如您在第二种情况下看到的那样,ASP.NET 工作线程仅在短时间内使用。这意味着池中有更多线程可用于服务其他请求。

所以总结一下,只有当你有一个真正的异步 API 时才使用异步操作。如果您在异步操作中进行阻塞调用,您将扼杀它的全部好处。


上下文同步怎么样。这会不会是您根本不想使用异步操作的开销? “实际异步执行的异步方法的开销完全取决于它是否需要使用 SynchronizationContext.Post 切换线程。如果需要,开销主要由它在恢复时执行的线程切换决定。这意味着当前 SynchronizationContext 使很大的不同。” (C# 5.0 中的异步,2012,Alex Davies)
@Darin 为什么释放主线程如此重要?线程有限制吗?
@Omtechguy 一个更好的解决方案是将非 ASP.NET 请求移动到 CDN。一个简单的 CDN 只是使用子域和单独的应用程序池来存储 javascript 和图像等物理文件。或者,您可以使用 NgineX / Lighttpd / Apache 来存储文件,或者您可以使用第三方服务,例如 Akamai(CDN 之王,但最昂贵)
我仍然很困惑。当调用 CheckPasswordAndSignInAsync 时,ASP.NET 从线程池中获取另一个线程并开始执行它,不是吗?如果不是,checking password procedure 在哪里执行?
G
Gaurang Dhandhukiya

通常,单个 HTTP 请求将由单个线程处理,从池中完全删除该线程,直到返回响应。使用 TPL,您不受此约束。任何进来的请求都开始与每个计算单元的延续,以计算能够在池中的任何线程上执行的响应。使用此模型,您可以处理比使用标准 ASP.Net 更多的并发请求。

是否会产生一些新任务,是否应该等待它。始终考虑那些 70 毫秒,大约是 70 毫秒。最大。任何方法调用都应该花费的时间。如果它更长,那么您的 UI 很可能不会感觉非常灵敏。


M
Muhammad Essa

在启动时看到大量并发请求或具有突发负载(并发突然增加)的 Web 应用程序中,使这些 Web 服务调用异步将提高您的应用程序的响应能力。异步请求与同步请求的处理时间相同。例如,如果请求发出需要两秒钟才能完成的 Web 服务调用,则无论是同步执行还是异步执行,该请求都需要两秒钟。但是,在异步调用期间,线程在等待第一个请求完成时不会被阻止响应其他请求。因此,当有许多并发请求调用长时间运行的操作时,异步请求可以防止请求排队和线程池增长。


如果您的 aspnet 应用程序主要由对其他 Web 服务器的调用组成,那么您在很大程度上表现为“网关”/“代理”,并且异步对此很有用。