FShaper
FShaper copied to clipboard
Support async/await
C# has native support for async/await, F# has async computation expressions. It should be possible to get close:
-
async
in method ->async { ... }
-
await
-> eitherlet!
ordo!
in the case of no binding. Expr will also require|> Async.AwaitTask
I also recommend generated async { ... }
to end with |> Async.StartAsTask
because some frameworks like WCF / SignalR / ... supports Task
by default where as they don't await F# asyncs.
@Thorium very good point. I have done this with the tests below.
I do wonder if supporting conversion to TaskBuilder would be better as it should be better performance, or to wait for native task support
Passing tests (more coverage may be needed):
[<Test>]
member this.``async no await writes as normal method`` () =
let csharp =
"""public async void Foo ()
{
return;
}"""
let fsharp =
"""member this.Foo() = ()"""
csharp |> Converter.run
|> should equal (formatFsharp fsharp)
[<Test>]
member this.``async with await writes as async computation method`` () =
let csharp =
"""public async void Foo ()
{
await Bar.WriteAsync();
}"""
let fsharp =
"""member this.Foo() = async { do! Bar.WriteAsync() |> Async.AwaitTask } |> Async.StartAsTask"""
csharp |> Converter.run
|> should equal (formatFsharp fsharp)
[<Test>]
member this.``await writes as async with let! in async computation`` () =
let csharp =
"""public async void Foo ()
{
var x = await Bar.WriteAsync();
return x;
}"""
let fsharp =
"""member this.Foo() = async { return Bar.WriteAsync() |> Async.AwaitTask } |> Async.StartAsTask"""
csharp |> Converter.run
|> should equal (formatFsharp fsharp)
[<Test>]
member this.``await writes as async with multiple let!`` () =
let csharp =
"""public async void Foo ()
{
var x = await Bar.GetX();
var y = await Baz.GetY();
return x + y;
}"""
let fsharp =
"""member this.Foo() = async { let! x = Bar.GetX() |> Async.AwaitTask
let! y = Baz.GetY() |> Async.AwaitTask
return x + y } |> Async.StartAsTask"""
csharp |> Converter.run
|> should equal (formatFsharp fsharp)