.NET 4.5框架库相当广泛地集成了C#-style基于任务的异步。在许多情况下,它们还会继续暴露APM样式的Begin / End方法对。 F#可以轻松地将这两种方法都适用于F#样式的异步计算。
我的问题是,给定一个IO绑定操作,它在框架中实现为Begin / End和基于任务的异步,在适应F#时,选择一个优于另一个是否有性能或内存优势异步?
例如,在.NET 4.5中,System.IO.Stream
同时包含BeginRead和ReadAsync。这意味着我可以做到这一点......
type System.IO.Stream with
member x.AsyncRead(buffer, offset, count) =
Async.FromBeginEnd(buffer, offset, count, x.BeginRead, x.EndRead)
或者我可以这样做......
type System.IO.Stream with
member x.AsyncRead(buffer, offset, count) =
x.ReadAsync(buffer, offset, count) |> Async.AwaitTask
有什么理由比较喜欢一个吗?我能想到的主要区别是,当第二个扩展方法返回时,读操作已经开始,但第一个扩展方法不是这样。
答案 0 :(得分:2)
FSharp.Core中已经定义了AsyncRead
扩展方法(implemented in terms of FromBeginEnd
)。 AwaitTask
只是Task.ContinueWith
上的一个薄包装器。因此,归结为Task
和async
的比较 - 这对作业更有效,或者正确。由于您正在使用async
,因此唯一相关的区别就是性能。我不是这方面的专家,但我认为async
和Task
解决了同样的问题,Task
具有CPU限制操作的优势。
我没有仔细阅读你的问题。我不知道明确的答案,但鉴于Task
和async
大致相同,我认为没有任何理由将Task
与async
打包在一起,除非这是你唯一的选择。 Begin/End
方法是一种更低级,更轻量级的抽象,因此看起来像是async
的更好的构建块。
一个辅助思想:AsyncRead
未被更改为使用Task
的事实可能具有指导意义。