gpt4 book ai didi

.net - 为什么需要在 F# 异步工作流中使用 "do! Async"样式函数?

转载 作者:行者123 更新时间:2023-12-02 07:25:15 25 4
gpt4 key购买 nike

我是 F# 异步工作流的新手。通常介绍该主题的代码和示例包含如下示例(已简化):

let sleepWorkflow = 
async{
printfn "Starting sleep workflow at %O" DateTime.Now.TimeOfDay
do! Async.Sleep 2000
printfn "Finished sleep workflow at %O" DateTime.Now.TimeOfDay
}

Async.RunSynchronously sleepWorkflow

我正在尝试理解 的必要性! Async.Sleep 2000 而不是 do Threading.Thread.Sleep(2000) 代替它。

据我了解,这两种方法都将在此时同步运行代码。

有什么区别(我想肯定有),什么时候应该使用一种方法而不是另一种方法?

最佳答案

不同之处在于,使用Thread.Sleep 会阻塞当前线程,使其无法执行任何其他操作,而Async.Sleep 会创建一个系统计时器,释放当前线程(以便它可以做其他事情)然后(在时间过去后)再次获取一个线程并运行其余代码。

如果您有大量并行运行的 async 工作流(因为为每个工作流分配一个专用线程会很昂贵)或者当您在 GUI 线程上运行代码时(有只有一个线程,你不应该阻塞它)。

为了更好地理解这一点,您可以将线程池​​线程数更改为 1 并使用同步和异步阻塞尝试以下代码:

System.Threading.ThreadPool.SetMinThreads(1, 1)
System.Threading.ThreadPool.SetMaxThreads(1, 1)

for i in 1 .. 5 do
async { System.Threading.Thread.Sleep(1000)
printfn "Done" } |> Async.Start

for i in 1 .. 5 do
async { do! Async.Sleep(1000)
printfn "Done" } |> Async.Start

在运行第一个 for 循环后,您将延迟 1 秒打印“完成”消息(因为一个线程被重复阻塞 1 秒)。

在运行第二个 for 循环后,您将在 1 秒后看到“完成”消息同时打印出来。这是因为异步等待实际上并没有阻塞线程,因此 5 个计时器将全部用完,然后使用 1 个可用线程进行打印(这几乎不需要时间)。

关于.net - 为什么需要在 F# 异步工作流中使用 "do! Async"样式函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33170933/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com