-->

C# async / await method to F#?

2020-03-01 09:09发布

问题:

I am trying to learn F# and am in the process of converting some C# code to F#.

I have the following C# method:

public async Task<Foo> GetFooAsync(byte[] content)
{
    using (var stream = new MemoryStream(content))
    {
        return await bar.GetFooAsync(stream);
    }
}

Where bar is some private field and GetFooAsync returns a Task<Foo>.

How does this translate to F#?

Here is what I currently have:

member public this.GetFooAsync (content : byte[]) = 
    use stream = new MemoryStream(content)
    this.bar.GetFooAsync(stream)

Which returns a Task.

回答1:

In F#, asynchrony is represented by the async computation builder, which is not an exact analog of Task, but can generally be used in place of one:

member public this.GetFooAsync (content : byte[]) = 
   async {
      use stream = new MemoryStream(content) 
      return! this.bar.GetFooAsync(stream) |> Async.AwaitTask
   } 
   |> Async.StartAsTask


回答2:

If you are converting async/await-intensive C# code to F#, it might get cumbersome because of the difference between F#'s async and Task and the fact that you always have to call Async.AwaitTask

To avoid that you can use FSharpx library, which has a task computation expression.

let tplAsyncMethod p = Task.Run (fun _ -> string p)

// awaiting TPL method inside async computation expression
let asyncResult = async {
                   let! value1 = tplAsyncMethod 1 |> Async.AwaitTask
                   let! value2 = tplAsyncMethod 2 |> Async.AwaitTask
                   return value1 + value2
                }

// The same logic using task computation expression
open FSharpx.Task
let taskResult = task {
                    let! value1 = tplAsyncMethod 1
                    let! value2 = tplAsyncMethod 2
                    return value1 + value2
                }

The result of asyncResult is Async<string> and the result of taskResult is Task<string>.



标签: f# c#-to-f#