使.NET 4.5异步适应F#

时间:2012-02-14 18:56:27

标签: f# .net-4.5

.NET 4.5框架库相当广泛地集成了C#-style基于任务的异步。在许多情况下,它们还会继续暴露APM样式的Begin / End方法对。 F#可以轻松地将这两种方法都适用于F#样式的异步计算。

我的问题是,给定一个IO绑定操作,它在框架中实现为Begin / End和基于任务的异步,在适应F#时,选择一个优于另一个是否有性能或内存优势异步?

例如,在.NET 4.5中,System.IO.Stream同时包含BeginReadReadAsync。这意味着我可以做到这一点......

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

有什么理由比较喜欢一个吗?我能想到的主要区别是,当第二个扩展方法返回时,读操作已经开始,但第一个扩展方法不是这样。

1 个答案:

答案 0 :(得分:2)

FSharp.Core中已经定义了AsyncRead扩展方法(implemented in terms of FromBeginEnd)。 AwaitTask只是Task.ContinueWith上的一个薄包装器。因此,归结为Taskasync的比较 - 这对作业更有效,或者正确。由于您正在使用async,因此唯一相关的区别就是性能。我不是这方面的专家,但我认为asyncTask解决了同样的问题,Task具有CPU限制操作的优势。

修改

我没有仔细阅读你的问题。我不知道明确的答案,但鉴于Taskasync大致相同,我认为没有任何理由将Taskasync打包在一起,除非这是你唯一的选择。 Begin/End方法是一种更低级,更轻量级的抽象,因此看起来像是async的更好的构建块。

一个辅助思想:AsyncRead未被更改为使用Task 的事实可能具有指导意义。