异步。从超时和cancelToken开始?

时间:2019-03-04 07:35:30

标签: asynchronous f# timeout cancellation cancellation-token

我有一个要运行的Async<'T>计算,并获得结果'T

我只有两个要求:

  1. 经过某些timeout:TimeSpan之后,我希望中止计算/ IO。
  2. 我想用cancellationToken运行它,以防万一我想在timeout通过之前中止它。

根据上述我的要求(1),您可能会认为Async.StartChild是一个不错的选择,因为它接受超时参数,但是不接受CancellationToken参数!

似乎API中其他接受cancelToken的Async.方法要么不返回任何内容(因此我无法等待结果),要么仅为Async<unit>工作,或者不不允许我将其与Async.StartChild结合使用来满足我的两个要求。

此外,我需要在async{}块内实现此功能,这意味着在其中使用Async.RunSynchronously(以防您建议this)看起来是有问题的还是难看的。 / p>

我能俯瞰一切吗?

谢谢!

1 个答案:

答案 0 :(得分:1)

hvester的注释中所述,在启动Child计算时,不需要传递CancellationToken。它将由父级共享,并将同时取消两者,例如参见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