gpt4 book ai didi

asynchronous - 为什么 Async.StartChild 不带 CancellationToken?

转载 作者:行者123 更新时间:2023-12-04 03:56:23 24 4
gpt4 key购买 nike

我正在努力理解 Async.[StartChild|Start] API 设计。
我想要的是启动一个异步进程,该进程根据到达 tcp 的命令执行一些 tcp 流读取和调用回调。

由于这个异步进程并没有真正返回任何单个值,所以我似乎应该使用 Async.Start .在某些时候,我想“关闭”我的 tcp 客户端,`Async.Start 采用 CancellationToken,这使我能够实现“关闭”。到目前为止一切顺利。

问题是,我想知道 tcp 客户端何时完成取消。一旦请求取消,就会完成一些缓冲区刷新工作,所以我不想在 tcp 客户端完成清理之前终止应用程序。但是Async.Start返回单位,这意味着我无法知道此类异步过程何时完成。所以,看起来像 Async.StartChild应该有帮助。我应该能够调用取消,当清理完成时,这个异步将调用链中的下一个延续(或抛出异常?)。但是... Async.StartChild不带 CancellationToken,只带超时。

为什么Async.StartChild仅实现取消策略的单一情况(超时)而不是公开更通用的方式(接受 CancellationToken)?

最佳答案

回答问题的第一部分——如果你需要做一些清理工作,你可以把它放在finally并且会在工作流取消时调用。例如:

let work = 
async {
try
printfn "first work"
do! Async.Sleep 1000
printfn "second work"
finally
printfn "cleanup" }

假设你使用 Async.Start 运行它, 等待 500ms 然后取消计算:
let cts = new System.Threading.CancellationTokenSource()
Async.Start(work, cts.Token)
System.Threading.Thread.Sleep(500)
cts.Cancel()

输出将是“第一个工作,清理”。如您所见,取消计算将运行所有 finally条款。

回答问题的第二部分 - 如果您需要等到工作完成,您可以使用 RunSynchronously (但是,也许您实际上并不需要异步工作流,如果您无论如何都在阻塞......)。

下面启动一个后台进程,500ms后取消主工作,然后同步启动主工作:
let cts = new System.Threading.CancellationTokenSource()

async {
do! Async.Sleep(500)
cts.Cancel() } |> Async.Start

try Async.RunSynchronously(work, cancellationToken=cts.Token)
with :? System.OperationCanceledException -> ()
printfn "completed"

这将打印“第一项工作,清理,完成” - 如您所见, RunSynchronously调用被阻塞,直到工作被取消。

关于asynchronous - 为什么 Async.StartChild 不带 CancellationToken?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50275211/

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