等价于 F# 中的 C# async main
Equivalent of C# async main in F#
我想知道什么与 F# 中的 C# 异步 main
等效。更重要的是,在 F# 程序中是否有来自 main
的 consuming/using 异步方法的特殊方式,还是只是等待完成的问题?
更具体地说,假设我们正在使用 .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()
我可以展示更多的表述,但我认为这些表述很重要。
我想部分答案在于回答这些其他问题
- "what does it mean to run an async main method" 和
- "what's the point of making main async?"
举个例子,异步 main
似乎主要是为了让其他地方有可能以异步方式调用 main
(在那些 main
不是真正的情况下"main",即单元测试等)。
在 F# 的情况下,我想至少有两件事阻止一个人从 return 进行异步计算 main
:
- EntryPointAttribute 为状态代码强制执行 int return 类型...对吗?
- 编译器可能不准备将异步计算作为程序的退出值来处理...对吗?
据我所知,F# 中没有 async main 等价物。
如果您查看幕后的 C# 实现,它看起来像这样:
private static void <Main>(string[] args)
{
Program.Main(args).GetAwaiter().GetResult();
}
Program.Main 是异步主线程。
我个人觉得这个模式有点可怕,具体取决于使用的 SynchronizationContext。
为了模拟 async main,我会:
let theAsyncTask : Async<int> = ...
[<EntryPoint>]
let main argv =
async {
do! Async.SwitchToThreadPool ()
return! theAsyncTask
} |> Async.RunSynchronously
theAsyncTask
是实际要做的工作,嵌入的async
切换到线程池,这样main
线程就可以安全地阻塞等待结果。
我想知道什么与 F# 中的 C# 异步 main
等效。更重要的是,在 F# 程序中是否有来自 main
的 consuming/using 异步方法的特殊方式,还是只是等待完成的问题?
更具体地说,假设我们正在使用 .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()
我可以展示更多的表述,但我认为这些表述很重要。
我想部分答案在于回答这些其他问题
- "what does it mean to run an async main method" 和
- "what's the point of making main async?"
举个例子,异步 main
似乎主要是为了让其他地方有可能以异步方式调用 main
(在那些 main
不是真正的情况下"main",即单元测试等)。
在 F# 的情况下,我想至少有两件事阻止一个人从 return 进行异步计算 main
:
- EntryPointAttribute 为状态代码强制执行 int return 类型...对吗?
- 编译器可能不准备将异步计算作为程序的退出值来处理...对吗?
据我所知,F# 中没有 async main 等价物。
如果您查看幕后的 C# 实现,它看起来像这样:
private static void <Main>(string[] args)
{
Program.Main(args).GetAwaiter().GetResult();
}
Program.Main 是异步主线程。
我个人觉得这个模式有点可怕,具体取决于使用的 SynchronizationContext。
为了模拟 async main,我会:
let theAsyncTask : Async<int> = ...
[<EntryPoint>]
let main argv =
async {
do! Async.SwitchToThreadPool ()
return! theAsyncTask
} |> Async.RunSynchronously
theAsyncTask
是实际要做的工作,嵌入的async
切换到线程池,这样main
线程就可以安全地阻塞等待结果。