Async.Start with timeout and cancellationToken?

断了今生、忘了曾经 提交于 2019-12-11 08:07:45

问题


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

I only have two requirements:

  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.

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!

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.

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.

Am I overlooking anything?

Thanks!


回答1:


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


来源:https://stackoverflow.com/questions/54978550/async-start-with-timeout-and-cancellationtoken

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!