【问题标题】:async/await - Is this understanding correct?async/await - 这种理解正确吗?
【发布时间】:2016-01-09 03:48:09
【问题描述】:

经过两个问题和很多困惑 - 我想知道我是否最终做对了。这是我的理解:

async/await只有一个目的 - 允许在已经异步任务完成后执行代码。 例如

async Task CallerMethod()
{
     await AsyncMethod();
     AnotherMethod();
}

允许AnotherMethod 在异步AsyncMethod完成之后执行,而不是在AsyncMethod开始之后立即执行。

async/await 永远不要使任何东西异步。它不会启动单独的线程(当然,除非等待的方法这样做),等等。

我的理解(最终)正确吗?

【问题讨论】:

  • 是的,这听起来很对 - 但请注意,即使 AsyncMethod 没有产生线程,您也可能会在另一个线程上结束 - 您的回调可以在任何线程池线程中产生
  • @Carsten 谢谢。假设 callback 你的意思是 AnotherMethod(); - 这将有一个非常重要的含义 - 我无法从中更新 UI - 这是真的吗?
  • 不,您可以安全地从中更新 UI。这样做的原因是每个线程都有一个SynchronizationContext,async/await 生成的代码使用它来调度完成异步方法的回调。在 WPF 的情况下(例如),该类是一个DispatcherSynchronizationContext,它确保在必要时将该方法调用回 Dispatcher 线程。 WinForms 有一个类似的类。
  • @TimDestan 感谢您的澄清!

标签: c# .net multithreading asynchronous async-await


【解决方案1】:

async/await 永远不会使任何事情异步。它不会启动单独的线程(当然,除非等待的方法这样做),等等。

是的。

换句话说,async/await 可以从异步的角度编写代码。也就是说,代码可以“异步等待”(await)操作完成,进而定义自己的异步操作(从async方法返回的任务,代表该方法的执行)。

【讨论】:

    【解决方案2】:

    虽然斯蒂芬的回答是正确的,但我想确保您还清楚了几点。

    async/await 从不做任何异步操作

    它使CallerMethod 成为异步方法。 CallerMethod 返回一个 Task 本身可以等待,CallerMethodCallerMethod 的工作本身完成之前返回那个任务,所以它是一个异步方法。

    它不会使AsyncMethod 异步;它已经是异步的。

    它不会启动一个单独的线程

    没错。这是一个常见的混淆来源。线程是并发的一个单元,它只是一种异步。类比通常会有所帮助。你可以把面包放在烤面包机里,等它烤好,然后做鸡蛋。可以将面包放入烤面包机,在吐司烤的时候煮鸡蛋,待鸡蛋烤好后再处理吐司。或者你可以雇两个厨师,一个煮鸡蛋,一个做吐司。首先是同步处理。第二个和第三个是异步的,但只有第三个是并发的。请注意,第三种解决方案是最昂贵的;线程是工人,工人并不便宜。

    使异步方法异步的原因并不是它是并发的——尽管它可能是并发的。使其异步的原因在于它为您提供了一种机制,允许您在等待其工作完成时执行其他操作await 只是写“这是我希望你在任务成功完成后运行的代码”的一种愉快的方式。

    【讨论】:

    • 谢谢。不过,我会注意到,当有人说“线程”时-他们(我们)可能不是指实际的线程(如您的第三个类比)。它们更确切地说是指任何时候两个操作同时发生,将您的第二个和第三个类比包装在一起。因此,无论是实际线程,还是只是磁盘驱动器工作 - 他们都会考虑这种“多线程”。无论如何-在这里不争论任何事情,这只是一些(也许是正确的)信息可以帮助您帮助他人。再次感谢!
    • @ispiro:这本身就暗示了一个常见的误解; Stephen 有一篇很棒的文章揭穿了硬件 I/O 在某种程度上是多线程的想法,我当然只能向您推荐它。搜索“Stephen Cleary 没有线程”,你会找到它。
    • 这是语义,但我认为 concurrent 在这里并不是最好的词。我们通常会同时调用第二个和第三个选项并发,因为同时执行两个操作,但只调用第三个 parallel 因为它需要多个厨师(或线程)并行运行。因此,表达式:“单线程并发”。
    • @i3arnon:当然,这很好。如果硬件正在执行并发操作,则可以在没有额外线程的情况下同时发生并发操作。
    • @HaraldDutch:在我的类比中,线程是一个工人——一个人。没有线程在烘烤。烤面包机不是人;它低于人的水平。就像您不问“哪个线程正在运行我的硬盘?”没有线程在运行您的硬盘;硬盘在低于线程级别的世界中运行。当您“等待”磁盘操作时,没有“磁盘线程”在后台运行。您可能会对我上面提到的 Stephen Cleary 的文章感兴趣。
    猜你喜欢
    • 2021-07-30
    • 2017-04-10
    • 2018-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-06
    相关资源
    最近更新 更多