【问题标题】:F# 6 .NET tasks - how to useF# 6 .NET 任务 - 如何使用
【发布时间】:2022-01-06 16:46:49
【问题描述】:

F# 6 introduced 支持 .NET 任务。

这个 sn-p 随处共享 - 但是调用和使用任务结果的正确方法是什么(例如 printf 它)?

let readFilesTask (path1, path2) =
   task {
        let! bytes1 = File.ReadAllBytesAsync(path1)
        let! bytes2 = File.ReadAllBytesAsync(path2)
        return Array.append bytes1 bytes2
   }

一个可行的选择是:

let result = readFilesTask ("filaA", "fileB")
printf $"%A{result.Result}"

但这是预期的使用方式吗?

【问题讨论】:

  • 在大多数情况下,您将使用期望通过Task<'T> 传递的库或框架,您只需与它进行互操作。这是主要的用例,并且 async 总是让人觉得使用起来有点烦人。
  • 是的,我很清楚。我的问题是关于稍后如何访问Task<'T> 的结果。

标签: f#


【解决方案1】:

有几种方法可以处理任务。什么是“预期”方式取决于您要达到的目标。

另请注意,对于许多应用程序,async 只是稍微慢一点,但更容易使用,因为它是“冷”的。

您可以使用let!do! 在另一个任务中消费一个任务:

task {
  let! x = someOtherTask ()
  do! andAnotherTask ()
  return x
}

您可以开始一项任务,而不是等待结果(即发即弃):

let foo () = 
  task {
    printfn "Done."
  }

foo () |> ignore // tasks are "hot" unlike asyncs

您可以使用Async.AwaitTask 将任务转换为Async<'t>

async {
  do! 
    task {
      printfn "Done."
    }
    |> Async.AwaitTask
}

你可以阻塞当前线程直到任务完成:

let foo () = 
  task {
    printfn "Done."
  }

let t = foo ()
t.Result

我预计大多数实际应用程序都会有很多 do!let! 语句,但只有少数 .Result 调用以避免阻塞。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-09
    相关资源
    最近更新 更多