【问题标题】:Async operation immediately awaited立即等待异步操作
【发布时间】:2014-09-12 19:01:27
【问题描述】:

我正在查看其他开发人员的这些代码行:

  bool isValid = await engine.GetTaskByIdAsync(taskId);
  if(isValid )
  ....

当我使用async操作时,它是在异步操作完成的同时做独立的工作:

  Task<bool> task = engine.GetTaskByIdAsync(taskId);

  //Do work that doesn't need the "task" variable

  bool completed = await task;
  if(bool)
  ....

似乎第一个示例启动了异步操作,然后立即开始等待。这里有什么我不明白的价值吗?

注意:此代码位于应用程序的数据访问层,因此不与用户界面交互。

【问题讨论】:

  • 好的,启动一个进程立即返回,如果你事先有逻辑有什么关系?
  • “似乎第一个示例启动了异步操作,然后立即开始等待”-await 导致我们在继续之前等待调用完成。
  • 没有等待任务的情况下,你会如何做那个程序员所做的事情?
  • @DanPantry 不。它没有。可悲的是,这是一个普遍的误解。它导致方法的其余部分作为等待任务的延续,在该任务完成时执行。这与等待该任务非常不同。
  • 使用立即等待是为了方便不锁定用户界面。

标签: c#


【解决方案1】:

这里有什么我不明白的价值吗?

绝对 - 这意味着虽然您需要操作返回的值才能进行更多工作,但您在等待时不会占用线程。如果您正在编写 GUI,这一点尤其重要,因为绑定 GUI 线程基本上意味着冻结 UI。

听起来您正在关注异步的“并行执行多项操作”方面,这很重要,但远非它的唯一好处。

【讨论】:

  • 好点,我只使用网络,所以这不是我通常处理的事情。我在数据访问层中找到了这段代码,所以很好奇是否可以从中收集到一些东西。
  • @ChrisHardie Web 应用程序仍然可以从异步中受益。它可以允许 Web 请求在不执行 CPU 绑定工作时不消耗线程池线程的时间,允许这些线程池线程为其他请求提供服务,从而允许服务器扩展它可以服务的可能并发请求的数量。跨度>
  • @Servy 首先提高网络服务器可用的线程数不是更好吗?添加 await 确实会引入开销,但不会神奇地增加系统可用的 cpu 周期数。虽然您在技术上是正确的,但我认为您最好正确调整您的网络服务器。
  • @AVee 不,await 不需要 需要一个实际的线程来完成任何工作。异步的全部 point 是你实际上并不使用线程,除非你有 CPU 密集型的工作要做。在正确编写的异步程序中执行非 CPU 绑定工作时确实没有线程。
  • @AVee:假设您有 1000 个请求同时执行,所有这些请求都需要执行一个基于 IO 的操作(例如 Web 服务调用)。使用 async/await,您可以摆脱单个线程(或者更确切地说,只有实际能够同时工作的线程数)。同步进行调用,您需要 1000 个线程,所有线程都被阻塞并且什么都不做,只是在它们之间占用 1GB 的堆栈空间。基本上,您假设阻塞的线程是免费的 - Servy 和我说它们不是。
【解决方案2】:

常见的错误是等待块。没有。

当前线程立即返回,函数的剩余部分注册为在异步任务完成时执行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-26
    • 1970-01-01
    • 2018-06-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多