使.NET 4.5异步到F#

使.NET 4.5异步到F#,f#,.net-4.5,F#,.net 4.5,NET4.5框架库相当广泛地集成了C风格的基于任务的异步。在许多情况下,它们还继续公开APM风格的开始/结束方法对。F#可以很容易地将任何一种方法适应于F#风格的异步计算 我的问题是,如果在框架中实现了一个IO绑定的操作,作为开始/结束和基于任务的异步,那么在适应F#async时,选择其中一个是否有性能或内存优势 例如,在.NET4.5中,System.IO.Stream同时具有和。这意味着我能做到 type System.IO.Stream with member x.AsyncRea

NET4.5框架库相当广泛地集成了C风格的基于任务的异步。在许多情况下,它们还继续公开APM风格的开始/结束方法对。F#可以很容易地将任何一种方法适应于F#风格的异步计算

我的问题是,如果在框架中实现了一个IO绑定的操作,作为开始/结束和基于任务的异步,那么在适应F#async时,选择其中一个是否有性能或内存优势

例如,在.NET4.5中,
System.IO.Stream
同时具有和。这意味着我能做到

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
或者我可以这样做

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
有什么理由选择其中一个而不是另一个吗?我能想到的主要区别是,当第二个扩展方法返回时,读取操作已经开始,但第一个扩展方法就不是这样了。

FSharp.Core中已经定义了一个扩展方法()。只是一层薄薄的外衣。因此,它归结为
任务
异步
的比较——哪一个更有效,或者更适合该作业。由于您使用的是
async
s,因此唯一相关的区别是性能。我不是这方面的专家,但我认为
async
Task
解决了同样的问题,因为
Task
在CPU限制的操作方面具有优势

编辑 我没有仔细阅读你的问题。我不知道确切的答案,但鉴于
任务
异步
大致相当,我认为没有任何理由将
任务
包装为
异步
,除非这是您唯一的选择
Begin/End
方法是一种较低级别、更轻量级的抽象,因此似乎是
async
s的更好构建块


一个附带的想法是:
AsyncRead
没有改为使用
Task
,这一事实可能很有启发性。

我知道AsyncRead已经存在,这只是一个例子。我的问题是,如果在框架中实现了一个IO绑定的操作,该操作同时作为开始/结束和基于任务的异步,那么在适应F#async时,选择一个操作是否有性能或内存优势?啊,对不起……我没有仔细阅读您的问题。我不知道答案,但我会选择
FromBeginEnd
,因为它增加的开销最小。在
任务
的基础上构建
异步
对于互操作之外的任何东西都是多余的。希望不会有太多开销,因为当C#5上线时,我感觉我们将在
任务
的基础上构建大量的
异步
。。。考虑到基于任务的异步只是C#5中异步的一种方式,我希望有人知道与我们习惯的F#相比,它在.NET 4.5中的优化程度有多高。基于事件的异步模式比
任务
存在的时间要长得多,所以我怀疑几乎总是会存在的(至少在BCL中)可用的
开始/结束
备选方案。其他一切都属于互操作范畴,互操作很少是最有效的。是BCL中使用基于任务的异步且没有开始/结束选项的位置的一个示例。我怀疑他们是否会删除任何现有的开始/结束对,但我希望在新API中看到仅任务异步的激增。