问题
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>
.
来源:https://stackoverflow.com/questions/40358820/c-sharp-async-await-method-to-f