.NET 4.5框架库相当广泛地集成了C#-style基于任务的异步.在许多情况下,它们还会继续暴露APM样式的Begin/End方法对.F#可以轻松地将这两种方法都适用于F#样式的异步计算.
我的问题是,给定一个在框架中实现的IO绑定操作,作为开始/结束和基于任务的异步,在适应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)
Run Code Online (Sandbox Code Playgroud)
或者我可以这样做......
type System.IO.Stream with
member x.AsyncRead(buffer, offset, count) =
x.ReadAsync(buffer, offset, count) |> Async.AwaitTask
Run Code Online (Sandbox Code Playgroud)
有什么理由比较喜欢一个吗?我能想到的主要区别是,当第二个扩展方法返回时,读操作已经开始,但第一个扩展方法不是这样.
FSharp.Core 中已经定义了扩展方法AsyncRead(根据 实现)。FromBeginEndAwaitTask只是一层薄薄的包装纸Task.ContinueWith。因此,归根结底,就是对Task和进行比较async——哪个更有效,或者更适合这项工作。由于您使用的是asyncs,唯一相关的区别是性能。我不是这方面的专家,但我认为async并Task解决了同样的问题Task具有 CPU 密集型操作的优势。
我没有足够仔细地阅读你的问题。我不知道明确的答案,但考虑到Task和async大致相同,我认为没有任何理由用 an 包裹Taska async,除非它是您唯一的选择。Begin/End方法是一种较低级别、更轻量级的抽象,因此似乎是更好的构建块asyncs 构建块。
AsyncRead一个辅助想法:没有改变使用的事实Task 可能是有启发性的。