如何用do!关键字等待Task<'a>?F#与C#异步互操作问题
F#与C#异步互操作:忽略泛型Task<'a>结果的最佳实践
问题场景
在F#中与C#异步类进行互操作时,若需要调用返回泛型Task<'a>的方法,异步等待其完成但忽略结果,会遇到do!关键字的适配问题。根据F#文档,do!可直接等待非泛型Task,示例如下:
task { do! obj.workAsync() // workAsync: () -> Task }
但当workAsync签名为() -> Task<'a>时,上述写法无法生效。
两种自定义转换方案
针对这个问题,我实现了两种将Task<'a>转为非泛型Task的辅助函数:
变体1:基于F# task表达式
let toNonGenericTask (res: Task<'a>) : Task = task { let! _ = res () }
变体2:基于Task.ContinueWith方法
let toNonGenericTask (res: Task<'a>) : Task = res.ContinueWith(fun (_: Task<'a>) -> ())
两种变体都能在以下场景中正常工作:
let processStuff () = task { do! obj.workAsync() |> toNonGenericTask }
疑问与最优解决方案
核心问题
- 哪种
toNonGenericTask实现更推荐? - 是否存在无需自定义辅助函数的简化方案?
最优简化方案(更新)
参考反馈后发现,无需编写自定义辅助函数,直接通过向上转型即可满足需求,写法简洁易读:
task { do! obj.workAsync() :> Task }
内容的提问来源于stack exchange,提问作者karanveer41
相关产品推荐
相关产品推荐

