异步。从超时和cancelToken开始? [英] Async.Start with timeout and cancellationToken?

查看:212
本文介绍了异步。从超时和cancelToken开始?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have an Async<'T> computation that I want to run, and obtain the result 'T.

我只有两个要求:


  1. 在某些<$ c $之后c> timeout:TimeSpan 已经过去,我希望中止计算/ IO。

  2. 我想使用 cancellationToken运行它以防万一我想在超时过去之前中止它。

  1. After certain timeout:TimeSpan has passed, I want the computation/IO to be aborted.
  2. I want to run it with a cancellationToken just in case I want to abort it before timeout 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆