F# 异步/并行组合

F# 异步/并行组合,f#,F#,我在F#中看到了一些将异步与并行相结合的示例。以下是MSDN示例: 这不是对线程的低效使用吗?为什么要为许多可能长期运行的IO类型操作使用新线程。这基本上不是在创建只需坐在那里等待的线程吗?快速回答:异步工作流是轻量级的用户空间线程。您可以创建大量这样的异步工作流,这有助于以更自然的方式构造您的程序,假设它具有异步、并发或并行计算。单个本机线程可以运行任意数量的异步工作流,并且异步工作流可以从一个本机线程传输到另一个本机线程。这允许您的程序有效地使用本机线程 异步工作流的基本特征是,在等待长时间

我在F#中看到了一些将异步与并行相结合的示例。以下是MSDN示例:
这不是对线程的低效使用吗?为什么要为许多可能长期运行的IO类型操作使用新线程。这基本上不是在创建只需坐在那里等待的线程吗?

快速回答:异步工作流是轻量级的用户空间线程。您可以创建大量这样的异步工作流,这有助于以更自然的方式构造您的程序,假设它具有异步、并发或并行计算。单个本机线程可以运行任意数量的异步工作流,并且异步工作流可以从一个本机线程传输到另一个本机线程。这允许您的程序有效地使用本机线程

异步工作流的基本特征是,在等待长时间运行(异步)操作的结果时,可以阻止异步工作流中的操作,而不会阻止本机线程。这允许单个本机线程运行多个异步工作流(一次一个)

在您链接到的特定示例中,
Async.Parallel
用于并行执行多个长时间运行的操作。异步工作流的使用使得程序的并行版本在结构上变得简单,同时避免了使用多个(昂贵的)本机线程因此,答案是否定的:这不会创建大量只需等待的本机线程。发生的情况是(相对)少量本机线程将运行这些异步工作流。当某个特定的异步工作流被阻塞,等待长时间运行的操作时,本机线程开始运行其他一些准备继续的异步工作流


关于并行编程,特别是异步工作流存在问题。具体来说,异步工作流是以(半)抢占方式执行的。基本上,执行异步工作流是为了在执行一些操作之后,一个特定的异步工作流进入队列,即使它不阻塞或等待长时间运行的操作,而另一个工作流则退出队列等待执行。这对并行性能来说是灾难性的,因为这意味着您的程序将使用与就绪工作流数量成比例的内存,而就绪工作流的数量可能远远大于CPU内核的数量。为了最大化并行性能,最好使用协作调度。这就是我为F#创建库的原因之一。

OK。这与C#中的情况不同,例如,如果您创建了大量运行异步IO操作的任务,这些任务会执行大量等待,这实际上是在浪费线程。没错,我指的是C#5之前的版本,应该提到这一点。但要确认的是,F#async工作流在节省线程方面与async Wait具有相同的优势,请更正您的“关于并行编程”一段中的?+1。如果可以的话,它将是+100,因为它简洁而有效地描述了一个许多人似乎误解的问题。