异步。从超时和cancelToken开始? [英] Async.Start with timeout and cancellationToken?
问题描述
我有一个要运行的 Async<'T>
计算,并获得结果'T
。
I have an Async<'T>
computation that I want to run, and obtain the result 'T
.
我只有两个要求:
- 在某些<$ c $之后c> timeout:TimeSpan 已经过去,我希望中止计算/ IO。
- 我想使用
cancellationToken运行它
以防万一我想在超时
过去之前中止它。
- After certain
timeout:TimeSpan
has passed, I want the computation/IO to be aborted. - I want to run it with a
cancellationToken
just in case I want to abort it beforetimeout
has passed.
根据我上面的要求(1),您可能认为 Async.StartChild
是一个不错的选择,因为它接受超时参数,但是,它不接受
According to my requirement (1) above, you might think that Async.StartChild
is a good candidate because it accepts a timeout parameter, however, it doesn't accept a cancellationToken parameter!
似乎API中的其他 Async。
方法都接受了cancelToken要么不返回任何东西(所以我无法等待结果),要么只为 Async< unit>
工作,或者不允许我将其与Async.StartChild达到我的两个要求。
It seems that the other Async.
methods in the API that accept a cancellationToken either don't return anything (so I cannot await for the result), or only work for Async<unit>
, or don't allow me a way to combine it with Async.StartChild to achieve both of my requirements.
此外,我需要在 async {}
块内实现此功能,这意味着使用 Async.RunSynchronously
放在其中(以防万一您建议此)看起来有问题或难看。
Also, I need to implement this inside an async{}
block, which means that using Async.RunSynchronously
inside it (just in case you suggest this) would look either problematic or ugly.
我能俯瞰一切吗?
谢谢!
推荐答案
如 hvester 的注释中所述,启动Child时无需传递CancellationToken计算。它将由父级共享,并将同时取消两者,例如,请参见此处。
As mentioned in the comments by hvester, you do not need to pass a CancellationToken when starting the Child computation. It will be shared by the Parent and would cancel both, see for example here.
let work dueTime = async{
do! Async.Sleep dueTime
printfn "Done" }
let workWithTimeOut timeForWork timeOut = async{
let! comp = Async.StartChild(work timeForWork, timeOut)
return! comp }
workWithTimeOut 200 400 |> Async.Start // prints "Done"
workWithTimeOut 400 200 |> Async.Start // throws System.TimeoutException
let cts = new System.Threading.CancellationTokenSource()
Async.Start(workWithTimeOut 400 200, cts.Token)
System.Threading.Thread.Sleep 100
cts.Cancel() // throws System.OperationCanceledException
这篇关于异步。从超时和cancelToken开始?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!