Async.Start的成本

时间:2012-04-02 08:52:41

标签: multithreading f# async-await mailboxprocessor

在mailboxprocessor循环中,我从先前存储在此类集合中的阻塞集合项中读取。由于我使用相同的循环来写入这样的集合,我需要将它作为一个线程启动。

async { process(queue.Take()) } |> Aysync.Start

执行是我的整个代码很慢(相对来说),我怀疑原因是我启动的新线程,虽然我用

启动了线程池
let toto = ThreadPool.SetMinThreads(300,300)

争论点可能在这里的另一个提示是,如果我只在队列为空时启动(并锁定整个部分)),我的运行时间变化很大,从350毫秒到7秒,而如果它不停留大约5-10秒。

我的问题是:

  • 无论如何我可以加速创建线程
  • 是否有一些结构已经处理了可以在邮箱处理器中使用的这种情况(消费者/生产者?)?

1 个答案:

答案 0 :(得分:1)

如果你需要创建数百个线程来运行I / O绑定计算,那么可能有些问题。如果计算是I / O绑定,则应该可以使用相对较少的线程运行它 - 如果它完全异步则意味着在任何等待期间线程都不会被阻塞。

因此,我认为在您的程序中首先要寻找的是线程被阻塞的地方,并将其替换为异步等待。

您的代码示例中有一个可疑的事情是队列,当您至少调用Take时,这可能会阻塞,这就是.NET中BlockingCollection的行为方式。您可以尝试使用BlockingQueueAgent替换它,它使用F#代理实现相同的功能,但提供可以在不阻塞线程的情况下调用的异步AsyncTake方法。