I was wondering what would be the equivalent of the C# async main
in F#. More to the point, is there a special way of consuming/using async methods from main
in an F# program or is it just a matter of waiting for completion?
To be more concrete, say we are using the .NET Core Generic Host.
In a C# program, main
might look like this:
class Program
{
static async Task Main(string[] args)
{
await new HostBuilder().Build().RunAsync();
}
}
In an F# program, my instinct would be to do something like this:
[<EntryPoint>]
let main args =
HostBuilder().Build.RunAsync().Wait()
...or...
[<EntryPoint>]
let main args =
HostBuilder().Build.RunAsync() |> Async.AwaitTask |> Async.RunSynchronously
...or...
[<EntryPoint>]
let main args =
async {
return HostBuilder().Build.RunAsync() |> Async.AwaitTask
} |> Async.RunSynchronously
...or just avoid async...but that's no fun...
[<EntryPoint>]
let main args =
HostBuilder().Build.Run()
There are a few more formulations I could show but I think these make the point.
I imagine that part of the answer lies in answering these other questions
Going by examples, async main
seems mostly to be about making it possible for other places to call main
in an async way (in those cases where main
is not really "main", ie. unit testing, etc).
In the case of F#, I imagine there are at least 2 things preventing one from just returning an Async computation from main
:
There is nothing equivalent to classes . Its a totally different paradigm. You can use structures in C. Have to code accordingly to make structures do the job.
There's no new / delete expression in C. The closest equivalent are the malloc and free functions, if you ignore the constructors/destructors and type safety.
The C++ equivalent is this ; that is, the keyword is the same. Do not forget the -> thats probably what the OP is missing.
delete keyword in C++ Delete is an operator that is used to destroy array and non-array(pointer) objects which are created by new expression. Delete can be used by either using Delete operator or Delete [ ] operator. New operator is used for dynamic memory allocation which puts variables on heap memory.
AFAIK there's no async main equivalent in F#.
If you look at C# implementation behind the scenes it looks like this:
private static void <Main>(string[] args)
{
Program.Main(args).GetAwaiter().GetResult();
}
Program.Main is the async main.
Personally I find this pattern slightly scary depending on what SynchronizationContext is used.
To emulate async main I would:
let theAsyncTask : Async<int> = ...
[<EntryPoint>]
let main argv =
async {
do! Async.SwitchToThreadPool ()
return! theAsyncTask
} |> Async.RunSynchronously
theAsyncTask
is the actual work to be done, the embedded async
switches to the thread pool so that the main
thread can safely block and await the result.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With