- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我是 F# 的新手,我一直在阅读 F# for Fun and Profit。在为什么使用 F#? 系列中,有一个 post描述异步代码。我遇到了 Async.StartChild
函数,我不明白为什么返回值是这样。
例子:
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
}
let nestedWorkflow = async {
printfn "Starting parent"
let! childWorkflow = Async.StartChild sleepWorkflow
// give the child a chance and then keep working
do! Async.Sleep 100
printfn "Doing something useful while waiting "
// block on the child
let! result = childWorkflow
// done
printfn "Finished parent"
}
我的问题是为什么不应该 Async.StartChild
只需返回 Async<'T>
而不是 Async<Async<'T>>
?你必须使用 let!
两次。 documentation甚至说:
This method should normally be used as the immediate right-hand-side of a let! binding in an F# asynchronous workflow [...] When used in this way, each use of StartChild starts an instance of childComputation and returns a completor object representing a computation to wait for the completion of the operation. When executed, the completor awaits the completion of childComputation.
在一些测试中,添加了一些对 sleep 的调用,似乎没有初始的let!
子计算从未开始。
为什么会有这种返回类型/行为?我习惯在 C# 中调用 async
方法将始终立即“启动”任务,即使您不这样做也是如此 await
它。事实上,在 C# 中,如果 async
方法不调用任何异步代码,它将同步运行。
编辑澄清:
这样做有什么好处:
let! waiter = Async.StartChild otherComp // Start computation
// ...
let! result = waiter // Block
与 if Async.StartChild
相比返回了 Async<'T>
:
let waiter = Async.StartChild otherComp // Start computation
// ...
let !result = waiter // Block
最佳答案
想法是这样的:你用 let wait = Async.StartChild otherComp
开始另一个异步计算(在后台)然后你让服务员回来。
这意味着 let! result = waiter
将阻塞并随时等待后台计算的结果。
如果Async.StartChild
会返回 Async<'t>
你会等待 let! x = otherComp
就在那里,它就像一个正常让!结果 = 其他补偿`
是的,F# Async-Workflows 只会在您执行类似 Async.Start...
的操作后启动或 Async.RunSynchronously
(它不像 Task
,通常在您创建它后立即运行)
这就是为什么在 C# 中您可以一次创建一个任务 ( var task = CreateMyTask()
)(即 Async.StartChild
部分)然后稍后使用 var result = await task
在那里等待结果(即 let! result = waiter
部分)。
Async.StartChild
返回 Async<Async<'T>>
而不是 Async<'T>
这是因为以这种方式启动的工作流应该表现得像一个子-task/process。当您取消包含的工作流时,子也应该被取消。
因此,在技术层面上,子工作流需要访问取消 token 而无需您明确传递它,这是 Async
的一回事- 使用 Bind
时在后台为您键入句柄(在这里又名 let!
)。
所以它必须是这种类型才能使取消 token 的传递起作用。
关于asynchronous - 为什么 Async.StartChild 返回 `Async<Async<' T>>`?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67723546/
当我运行以下测试(使用 F#2.0 构建)时,我得到了 OutOfMemoryException。在我的系统上出现异常大约需要 5 分钟(如果它作为 x86 进程运行,则 i7-920 6gb ram
我正在尝试等待超时事件。我在函数 startAwaitEventWithTimeout 后面对此进行了抽象。目前我的代码看起来像这样(包括一些调试输出消息): let startAwaitEventW
我正在努力理解 Async.[StartChild|Start] API 设计。 我想要的是启动一个异步进程,该进程根据到达 tcp 的命令执行一些 tcp 流读取和调用回调。 由于这个异步进程并没有
假设 asyncSendMsg不返回任何内容,我想在另一个异步块中启动它,但不等待它完成,这之间有什么区别: async { //(...async stuff...) for msg
您好,我正在使用此处显示的 roundabout.js 实现带有 5 个图像的环形交叉路口 http://fredhq.com/projects/roundabout/demos/standard 所
我是 F# 的新手,我一直在阅读 F# for Fun and Profit。在为什么使用 F#? 系列中,有一个 post描述异步代码。我遇到了 Async.StartChild函数,我不明白为什么
我是一名优秀的程序员,十分优秀!