f# - 等效于 F# 中的 C# async main
问题描述
我想知道main
F# 中的 C# async 相当于什么。更重要的是,是否有一种特殊的方式可以在 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# 的情况下,我想至少有 2 件事阻止了一个从返回异步计算的事情main
:
- 对状态代码强制执行 int 返回类型的 EntryPointAttribute ......对吗?
- 编译器可能没有准备好将异步计算作为程序的退出值来处理......对吗?
解决方案
AFAIK 在 F# 中没有异步主等效项。
如果您查看幕后的 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
线程可以安全地阻塞并等待结果。
推荐阅读
- python - 训练/测试拆分在每个拆分中保留类比例
- spring - 如何使用带有嵌套状态机的弹簧状态机
- autodesk-forge - 集成 ant design 后查看器元素损坏
- amazon-web-services - 空 S3 存储桶 | 接入点 ARN 区域为空
- rabbitmq - rabbitmq 收到与任何主题不匹配的消息
- visual-studio - 在 Visual Studio 2019 的 lambda 表达式中使用 x
- c - MuPDF - 使给定的类似函数从文本中生成句子数组(C 语言)
- jdbc - Oracle 错误 - 失败:java.library.path 中没有 ocijdbc19
- android - android inputType="number" 和 "numberPassword" 不同的键盘,如何制作相同的键盘?
- angular - 使用角度处理 onblur 事件