C# async / await 方法到 F#?

C# async / await method to F#?

我正在尝试学习 F#,并且正在将一些 C# 代码转换为 F#。

我有以下 C# 方法:

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

其中 bar 是一些私有字段,GetFooAsync returns 是 Task<Foo>.

这如何转化为 F#?

这是我目前拥有的:

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

其中returns一个Task.

在 F# 中,异步由 async 计算构建器表示,它不是 Task 的精确模拟,但通常可以用来代替一个:

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

如果您要将 async/await 密集型 C# 代码转换为 F#,由于 F# 的 asyncTask 之间的差异以及事实上,你总是必须打电话给 Async.AwaitTask

要避免这种情况,您可以使用 FSharpx 库,它有一个 task 计算表达式。

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
                }

asyncResult的结果是Async<string>taskResult的结果是Task<string>