任务表达式中的代码在创建任务之前执行。

huangapple go评论60阅读模式
英文:

Code inside a task expression is executed before the task is created

问题

考虑以下代码:

let makeTask n =
    task { return longRunningFunc n }

假设花括号内的所有内容都是任务的一部分,我期望这段代码等同于:

let makeTask n =
    Task.Run(fun () -> longRunningFunc n)

但实际上它等同于:

let makeTask n =
    let value = longRunningFunc n
    Task.Run(fun () -> value)

这既出乎意料,也不太理想,特别是在尝试并行运行多个这样的任务时:

let myTask =
    Array.init 100 makeTask   // 错误:对 longRunningFunc 的调用是顺序执行的
        |> Task.WhenAll

请注意,async 构造器的行为符合预期。我知道任务是“热”的,而 F# 的异步是“冷”的,但我认为这并不能解释这个差异。

我的问题:

  1. 为什么 task 构造器会有这种行为,有没有相关的文档说明?
  2. 是否有可能让 task 构造器按预期将对 longRunningFunc 的调用移到 Task.Run 中?
英文:

Consider the following:

let makeTask n =
    task { return longRunningFunc n }

Under the assumption that everything inside the curly braces is part of the task, I would expect this to be equivalent to:

let makeTask n =
    Task.Run(fun () -> longRunningFunc n)

But it is apparently actually equivalent to:

let makeTask n =
    let value = longRunningFunc n
    Task.Run(fun () -> value)

Which is both unexpected and far less desirable, for example, when attempting to run many such tasks in parallel:

let myTask =
    Array.init 100 makeTask   // oops: calls to longRunningFunc occur sequentially
        |> Task.WhenAll

Note that the async builder behaves as expected. I understand that tasks are "hot", while F# asyncs are "cold", but I don't think that explains this discrepancy.

My questions:

  1. Why does the task builder behave this way, and is it documented anywhere?
  2. Is it possible to get the task builder to move the call to longRunningFunc into Task.Run, as expected?

答案1

得分: 0

F#编译器团队表示这是正确的行为。在任务表达式的顶部执行一个虚拟任务(例如do! Task.Delay(1))可以修复这个问题,但并不十分优雅。嗯,好吧。

英文:

The F# compiler team says this is the correct behavior. Executing a dummy task at the top of the task expression (e.g. do! Task.Delay(1)) would fix the problem, but isn't very elegant. Oh well.

huangapple
  • 本文由 发表于 2023年8月9日 06:18:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/76863511.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定