F# 等待任务并使用其结果

And*_*rei 0 .net f# .net-core

我对 F# 有点陌生,我正在尝试在 F# 模块中使用一些 C# 类。

let getApps (context: MyContext) =
    context.Provider.GetService<AppRepository>().GetActiveAsync().Result
    |> List.ofSeq
    |> List.map printName
    |> ignore
Run Code Online (Sandbox Code Playgroud)

我心里的 C# 开发人员尖叫道:.Result太糟糕了。所以我的问题是,如何将此代码重构为更优雅的方式,并利用 F# 中适当的异步编程。

我一直在尝试使用不同的变体:

|> Async.AwaitTask
|> Async.RunSynchronously
Run Code Online (Sandbox Code Playgroud)

但它看起来很丑而且不短,并不是说我不确定它是否有效地使用处理器时间。

Tom*_*cek 5

要记住的一件事是,这Async.RunSynchronously与访问基本相同Result。这两个操作都会阻塞当前线程,等待后台操作完成,然后给出结果。

async { .. }这意味着如果您需要使用 等待结果,那么使用是没有意义的RunSynchronously。(除了它RunSynchronously有一个又长又难看的名字,它明确而清晰地告诉你这就是正在发生的事情!)

如果您可以构建代码以便不需要等待,那么值得进行更改getApps以异步返回结果:

let getApps (context: MyContext) = async {        
  let! repos = 
    context.Provider.GetService<AppRepository>().GetActiveAsync()
    |> Async.AwaitTask
  return repos |> List.map printName }
Run Code Online (Sandbox Code Playgroud)

然后,您可以从另一个块调用它async { .. },并最终使用在后台启动计算Async.Start。但是,如果您要使用Async.RunSynchronously.