我有一些用c#写的东西,可以执行并发代码,大量使用任务并行库(任务和未来延续链)。
我现在正在将其移植到F#,并试图找出使用F#异步工作流与第三方公共关系中的构造的优缺点。我倾向于第三方物流,但我认为这两种方式都可以做到。
有没有人有关于用F#编写并发程序的技巧和智慧与大家分享?
发布于 2009-12-09 12:49:46
这个名称很好地概括了不同之处:异步编程与并行编程。但在F#中,你可以混合搭配。
F#异步工作流
当您希望异步执行代码时,即启动任务而不等待最终结果时,F#异步工作流非常有用。最常见的用法是IO操作。让你的线程在一个空闲的循环中等待你的硬盘完成写操作,这会浪费资源。
如果您以异步方式开始写入操作,则可以挂起线程,并在稍后通过硬件中断将其唤醒。
任务并行库
.NET 4.0中的任务并行库抽象了任务的概念-比如解码MP3,或者从数据库中读取一些结果。在这些情况下,您实际上想要计算的结果,并在稍后的某个时间点等待操作的结果。(通过访问.Result属性。)
您可以轻松地混合和匹配这些概念。例如,在TPL Task对象中执行所有IO操作。对于程序员来说,你抽象出了“处理”额外线程的需求,但在幕后,你正在浪费资源。
像wise一样,您可以创建一系列F#异步工作流并并行运行它们(Async.Parallel),但随后您需要等待最终结果(Async.RunSynchronously)。这使您不必显式地启动所有任务,但实际上您只是并行执行计算。
根据我的经验,我发现TPL更有用,因为我通常希望并行执行N个操作。然而,当有一些事情在“幕后”进行时,例如反应式代理或邮箱类型的事情,F#异步工作流是理想的。(您向某个对象发送消息,它会对其进行处理,然后将其发回。)
希望这能有所帮助。
发布于 2009-12-10 15:40:45
在4.0中,我会说:
也可以进行混合和匹配。他们已经添加了支持将工作流作为任务运行,并使用TaskFactory.FromAsync创建遵循异步开始/结束模式的任务。TPL相当于Async.FromBeginEnd或Async.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还值得注意的是,异步工作流运行时和第三方公共许可证都将创建一个额外的内核原语(事件),并使用WaitForMultipleObjects来跟踪I/O完成情况,而不是使用完成端口和回调。这在某些应用程序中是不可取的。
https://stackoverflow.com/questions/1871168
复制相似问题