【问题标题】:Do we still need to use await in c#?我们还需要在 c# 中使用 await 吗?
【发布时间】:2021-12-28 20:54:50
【问题描述】:

await 运算符暂停对封闭异步方法的评估,直到其操作数表示的异步操作完成

但是根据这个post

//You can access the Result property of the task, 
//which will cause your thread to block until the result is available:

string code = GenerateCodeAsync().Result;

这是否意味着我们不再需要await?因为如果我们使用await,我们必须将函数更改为async,这会使逻辑复杂化。但是访问任务的结果属性不需要这个

【问题讨论】:

  • 正如评论所暗示的,使用 await/async 使得这段代码_不会阻塞当前线程。这可能很重要,例如,如果您在服务器上调用此函数,那么您可能会遇到线程不足的风险。 (如果没有可用的线程,服务器将不得不拒绝新连接,因为它们只是在等待)。或者如果正在使用 UI 线程,您的 UI 将在等待结果时冻结。我
  • 嗯,加上'still'这个词,就不再重复了吗?
  • 使用.Result 基本上将整个异步点砸在地上,然后在其上跳舞,唱“neh neh neh”。它非常有害,并且在某些情况下还可能导致死锁。永远不要那样做(关于“除非你知道它已经成功完成”有一个小小的警告,但这不适用于一般情况)。所以是的:你需要await

标签: c#


【解决方案1】:

100 倍是的 - await 很重要。 .Result 将阻塞调用线程,直到产生结果。 await 允许运行时仅在需要时挂起和唤醒后续代码,而不阻塞任何线程。实际上,await 可以在完全不同的线程上唤醒。

一点点历史花絮:Task<T> 和它的 .Result 作为 C# 4.0 和任务并行库的一部分被添加,远远早于 asyncawait

【讨论】:

  • 谢谢。我仍然对等待感到困惑。您能否回答示例代码中更新后的问题?
  • @camino 如果您还有其他问题,请在另一个问题中提问
  • @SirRufo 感谢您的建议。我会再发一个
【解决方案2】:

我认为异步/等待模式的一个常见误解是暂停执行 == 阻塞结果。然而,这不是真的。当您调用 await 时,您的程序实际上并没有停止执行,它会将线程推入等待队列,该队列将在 IO 完成时复活。这允许其他任务同时运行。虽然从技术上讲,您始终可以阻止结果并获得相同的代码输出,但使用 await 会使您的代码运行得更快。

【讨论】:

  • “更快”不是正确的词;通常,单个操作会稍快没有异步。异步不是关于“更快” - 它是关于“可扩展”。当你有很多的事情发生时,你就会获得绩效奖励。
  • 如果您有很多并发的 IO 绑定任务,您的代码将(几乎可以肯定)运行得更快
  • 感谢您澄清误解
【解决方案3】:

GenerateCodeAsync().Result 在这种情况下只是从您的代码中删除异步。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-04
    • 2021-09-11
    • 2020-11-22
    • 2020-08-22
    • 1970-01-01
    • 2015-10-24
    • 2019-08-26
    • 2022-07-15
    相关资源
    最近更新 更多