【问题标题】:Does let!/do! always run the async object in a new thread?让!/做!总是在新线程中运行异步对象?
【发布时间】:2015-06-17 18:41:20
【问题描述】:

在 F# 上的 wikibook 中有一小部分内容:

什么让!怎么办?#

let! 在自己的线程上运行async<'a> 对象,然后它立即 将当前线程释放回线程池。当let! 返回时, 工作流的执行将在新线程上继续,这可能 或者可能不是工作流开始的同一个线程。

我在书籍或网络上没有找到任何其他地方表明这一事实(以粗体突出显示)。

无论异步对象包含什么(例如Thread.Sleep())以及它是如何启动的(例如Async.Start),这对所有let!/do!是否都是如此?

查看github 上的F# 源代码,我找不到在新(TP) 线程上执行绑定调用的位置。魔法发生在代码的什么地方?

【问题讨论】:

    标签: f#


    【解决方案1】:

    你觉得这句话的哪一部分令人惊讶?单个异步的部分可以在不同的线程池线程上执行,或者线程池线程必须在每次绑定时被释放和获取?

    如果是后者,那我同意——这听起来不对。查看code,只有少数几个地方有一个新工作项在线程池中排队(即少数Async 模块函数在内部使用queueAsync),而Async.SwitchToNewThread 产生了一个非线程池线程并在那里运行延续。单独绑定似乎不足以切换线程。

    然而,该声明的精神似乎与前者有关 - 不保证 async 块的某些部分将在同一线程上运行。您运行的确切线程应该被视为实现细节,当您让出控制权并等待某些结果时,您可以确定至少在某些时候您将登陆不同的线程。

    【讨论】:

    • 我已经更新了我的问题以澄清一点,但它是后者。当我阅读它时,我将“let!在自己的线程上运行异步对象”明确解释为“让!在 new (TP) 线程中运行异步对象”,这可能不是它的意思.很高兴得知我并不是唯一一个这样认为的人。
    【解决方案2】:

    没有。异步操作可能会在当前线程上同步执行,也可能最终在不同的线程上完成。这完全取决于相关异步 API 的实现方式。

    请参阅Do the new C# 5.0 'async' and 'await' keywords use multiple cores? 以获得体面的解释。 F#和C# async的实现细节不同,但总体原理是一样的。

    实现F#async计算表达式的构建器是here

    【讨论】:

      猜你喜欢
      • 2022-01-08
      • 1970-01-01
      • 2010-10-10
      • 1970-01-01
      • 2016-10-05
      • 2016-03-29
      • 1970-01-01
      • 1970-01-01
      • 2020-09-12
      相关资源
      最近更新 更多