我有一些东西写在c#执行并发码,使得大量使用的任务并行库(任务和未来延续的链)。

我现在移植这F#而我试图找出的优点和缺点使用F#异步的工作流程与该结构在TPL。我倾向TPL,但我认为这是可以做到任何一种方式。

任何人都不会有的技巧和智慧,写并发程序,在F#分享?

有帮助吗?

解决方案

名称几乎总结的差:<强>异步编程对的平行编程。但在F#中,你可以混合和匹配。

F#异步工作流

F#异步工作流是有用的,当你想有代码异步执行,即开始一个任务,并为最终的结果不是等着。这方面最常见的用法是IO操作。有你的线程在空闲循环,等待您的硬盘写完浪费资源坐在那里。

如果你开始写操作异步可以挂起线程,并经硬件中断后唤醒。

任务并行库

在.NET 4.0的任务并行库抽象任务的概念 - 诸如解码MP3,或读取从数据库的一些结果。在这种情况下,你真正想要的计算结果,并在某个时间点后正在等待手术的结果。 (通过访问。结果属性。)

可以容易地混合和匹配这些概念。比如做所有的IO操作的TPL任务对象。对程序员你已经提取了要“对付”这些额外的线程,但在幕后,你这是在浪费资源。

喜欢聪明人,你可以创建一系列的F#异步工作流程和并行运行这些(Async.Parallel),但是你需要等待最终结果(Async.RunSynchronously)。这使您不需要显式启动的所有任务,但实际上你只是在执行并行计算。

在我的经验,我发现TPL是比较有用的,因为通常我想并行执行个运算。然而,F#异步工作流是理想的时候有是怎么回事东西“幕后”如反应剂或邮箱类型的事情。 (你送东西的消息,它处理它并将其发送回。)

希望有所帮助。

其他提示

在4.0我会说:

  • 如果你的功能是连续的,使用异步的工作流程。他们只是读取得更好。
  • 使用TPL为其他一切。

这也有可能混合和匹配。他们已经增加了支持在运行一个工作流程作为一项任务而创建的任务,按照异步开始/端模式的使用 TaskFactory.FromAsync, ,相当于TPL 异步.FromBeginEndAsync.BuildPrimitive.

let func() =
    let file = File.OpenRead("foo")
    let buffer = Array.zeroCreate 1024
    let task1 = Task.Factory.FromAsync(file.BeginRead(buffer, 0, buffer.Length, null, null), file.EndRead)
    task1.Start()

    let task2 = Async.StartAsTask(file.AsyncRead(1024))
    printfn "%d" task2.Result.Length

这也是值得注意的两个异步的工作流程的运行和TPL要创建一个额外的核心原语(一件)和使用 WaitForMultipleObjects 跟踪I/O完成,而不是使用完成港口和回调。这是不可取的,在一些应用程序。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top