我想知道F#中的C#异步main
相当于什么。更重要的是,在F#程序中是否有一种特殊的方法来使用/使用main
中的异步方法,还是只是等待完成?
更具体地说,假设我们正在使用.NET Core通用主机。
在C#程序中,main
可能看起来像这样:
class Program
{
static async Task Main(string[] args)
{
await new HostBuilder().Build().RunAsync();
}
}
在F#程序中,我的本能是做这样的事情:
[<EntryPoint>]
let main args =
HostBuilder().Build.RunAsync().Wait()
...或...
[<EntryPoint>]
let main args =
HostBuilder().Build.RunAsync() |> Async.AwaitTask |> Async.RunSynchronously
...或...
[<EntryPoint>]
let main args =
async {
return HostBuilder().Build.RunAsync() |> Async.AwaitTask
} |> Async.RunSynchronously
...或者只是避免异步...但这没意思...
[<EntryPoint>]
let main args =
HostBuilder().Build.Run()
我可以显示更多的公式,但我认为这些是正确的。
我想答案的一部分在于回答其他问题
通过示例来看,异步main
似乎主要是为了使其他地方可以异步方式调用main
(在main
并非真正“主要”的情况下”,即单元测试等)。
对于F#,我想至少有两件事阻止一个人仅从main
返回异步计算:
答案 0 :(得分:7)
AFAIK在F#中没有异步主要等效项。
如果您在后台查看C#实现,则它看起来像这样:
private static void <Main>(string[] args)
{
Program.Main(args).GetAwaiter().GetResult();
}
Program.Main是异步main。
我个人认为,根据使用哪种SynchronizationContext,这种模式会有些吓人。
要模拟异步主服务器,我将:
let theAsyncTask : Async<int> = ...
[<EntryPoint>]
let main argv =
async {
do! Async.SwitchToThreadPool ()
return! theAsyncTask
} |> Async.RunSynchronously
theAsyncTask
是要完成的实际工作,嵌入式async
切换到线程池,以便main
线程可以安全地阻塞并等待结果。