The .NET 4.5 framework libraries integrate C#-style Task-based async fairly extensively. In many cases, they also continue to expose APM-style Begin/End method pairs. F# can easily adapt either method to F#-style asynchronous computations.

My question is, given an IO-bound operation that's implemented in the framework as both Begin/End and Task-based async, is there a performance or memory advantage to choosing one over the other when adapting to F# async?

For example, in .NET 4.5, System.IO.Stream has both BeginRead and ReadAsync. That means I can do this...

type System.IO.Stream with
    member x.AsyncRead(buffer, offset, count) =
        Async.FromBeginEnd(buffer, offset, count, x.BeginRead, x.EndRead)

Or I can do this...

type System.IO.Stream with
    member x.AsyncRead(buffer, offset, count) =
        x.ReadAsync(buffer, offset, count) |> Async.AwaitTask

Is there any reason to prefer one over the other? The main difference that I can think of is that the read operation will have already started when the second extension method returns, but not so with the first extension method.

Edit
Report