【问题标题】:Web API async method with AngularJSAngularJS 的 Web API 异步方法
【发布时间】:2015-03-30 01:52:20
【问题描述】:

我刚开始使用 AngularJSMVC 5,我一直在考虑使用 Web APIAngularJS,因为这似乎是将数据加载到客户端模型的好解决方案。

但是我注意到相当多的指南使用返回 Task<Model> 的异步操作,我不明白这比仅使用标准 Web API 操作有什么好处(例如:http://monox.mono-software.com/blog/post/Mono/233/Async-upload-using-angular-file-upload-directive-and-net-WebAPI-service/http://www.asp.net/web-api/overview/getting-started-with-aspnet-web-api/build-a-single-page-application-%28spa%29-with-aspnet-web-api-and-angularjs )。

由于这些对 Web API 的调用无论如何都是异步的,我不知道为什么我们需要使这些方法调用异步。只使用标准的 Web API 调用不是更好吗?

我不知道 stackoverflow 是否适合这种情况,但我希望能解释一下为什么以这种方式进行调用。

【问题讨论】:

标签: c# asp.net .net async-await


【解决方案1】:

async-await 在服务器上的好处是可扩展性和性能。当您将同步(阻塞)操作替换为异步(非阻塞)操作时,您可以释放以前阻塞等待的线程,您可以使用这些线程同时处理其他请求。

async-await 让您可以用更少的资源做更多的事情。

假设我们有这个同步方法:

public void Process()
{
    for (int i = 0; i < 1000; i++)
    {
        Math.Sqrt(i);
    }

    Thread.Sleep(3000); // sync I/O
}

通过async:

public async Task ProcessAsync()
{
    for (int i = 0; i < 1000; i++)
    {
        Math.Sqrt(i);
    }

    await Task.Delay(3000) // async I/O
}

我们可以使用单个线程来处理同一方法的多个请求,因为当您await异步操作时,处理请求的线程被释放了。

【讨论】:

  • 我明白 async-await 做了什么我不明白的是为什么在其中一些方法中他们费心在我看不到任何好处的地方使用它。例如,在一种方法中,他们等待异步调用,该方法的所有其余部分都是检查结果是否为空,是否返回一个值,如果不是则返回不同的值。因此,既然除了等待异步调用完成之外,您实际上并没有执行任何其他操作,为什么还要在那里使用 await 呢?
  • @Serberuss 你怎么知道没有其他操作?想象一下,您在确切的时间收到来自不同客户的请求。大多数 Web API 应用程序并不局限于单个同步客户端。
  • 也许我把它与同步 web 操作调用混淆了,因为我从来没有看到 async-await 用于存储库调用之类的东西,我认为它类似于 web 服务调用,除了它可以在客户端异步使用
  • 使用async-await 仅在操作真正异步(主要是 I/O)时才有意义。如果您可以选择使用这些操作的异步版本,您将能够同时处理更多请求。
  • 好吧更有意义。我不会用太多问题打扰您,非常感谢您的解释
【解决方案2】:

再举一个例子:

假设有 2 个请求,其中一个被困在等待数据库中 2 秒,另一个被困在应用程序逻辑中 2 秒。

没有异步,在请求进入 1 秒时,有 2 个线程正在使用。

使用异步(一直到数据库调用),在请求进入 1 秒时,有 1 个线程正在使用,处理应用程序逻辑。另一个请求处于等待状态(未使用线程)。

两个请求都需要 2 秒,但在异步场景中,活动线程的数量会在某些请求持续时间内减少

【讨论】:

  • 所以你是说你不会从客户端的角度注意到任何东西,但服务器这样做更有效?我仍然不完全确定为什么我没有在对进行数据库调用的 MVC 操作的同步调用中或在 WPF 应用程序中看到这一点。
  • 是的,它会影响线程池,在 .net 中,每个活动线程的内存影响可能约为 1mb。所以你只会在数百个并发请求的级别上真正注意到。
【解决方案3】:

服务器端的异步等待不是启用/增强异步 XMLHttpRequests(AJAX 调用)。它是为了启用 await 关键字并处理在较低级别的框架代码和服务器端代码中返回任务的方法,如果您选择实现任何一个。想到这个例子:

底层 Web API 的控制器调度程序启动控制器以响应请求,并告诉它执行操作。然后它需要查看响应并根据结果(错误等)采取措施。如果它同步执行该调度,则线程被调度程序阻塞,等待操作完成,而不必如此。在异步上下文中,该调度程序可以等待来自控制器的响应,并释放线程以供其他任务运行。当原始控制器的操作完成后,任何空闲线程都可以从第一个线程停止的地方开始处理并处理调度的其余部分。

【讨论】:

    猜你喜欢
    • 2018-05-15
    • 2020-03-10
    • 1970-01-01
    • 2015-05-12
    • 2014-05-15
    • 1970-01-01
    • 2015-06-04
    • 2015-01-14
    • 1970-01-01
    相关资源
    最近更新 更多