Asynchronous 在FromContinuations中使用取消延续
我试图通过Asynchronous 在FromContinuations中使用取消延续,asynchronous,f#,cancellation,continuations,Asynchronous,F#,Cancellation,Continuations,我试图通过async来理解async工作流。如果在异步计算中使用CancellationToken,F#async工作流将自动传播它,以便您可以在任何地方访问它,但您仍然需要明确检查是否触发了取消,并自己引发异常。这不会在同步用户代码的任何地方“自动”发生 这意味着问题有两个部分。1) 如何访问取消令牌以及2)如何检查其是否已被取消 第二部分有点棘手,因为您需要使用Async.CancellationToken,但这会返回Async,因此您必须在FromContinuations代码之外的异步块
async来理解async
工作流。如果在异步计算中使用CancellationToken
,F#async工作流将自动传播它,以便您可以在任何地方访问它,但您仍然需要明确检查是否触发了取消,并自己引发异常。这不会在同步用户代码的任何地方“自动”发生
这意味着问题有两个部分。1) 如何访问取消令牌以及2)如何检查其是否已被取消
第二部分有点棘手,因为您需要使用Async.CancellationToken
,但这会返回Async
,因此您必须在FromContinuations
代码之外的异步块中调用它。第二部分只是调用代码中的某个地方的tok.throwifcancellationrequest()
在执行除名之前,检查是否取消:
let asyncComputation divisor = async {
let! tok = Async.CancellationToken
return! Async.FromContinuations
(fun (success, except, cancel) ->
try
printfn "Going to sleep..."
Threading.Thread.Sleep 3000
printfn "...waking up"
tok.ThrowIfCancellationRequested()
1 / divisor |> ignore
printfn "Calling success continuation..."
success ()
with
| :? OperationCanceledException as e ->
printfn "Calling cancellation continuation..."
cancel e
| e ->
printfn "Calling exception continuation..."
except e) }
这不会在等待时取消。如果需要,您需要能够取消等待操作,例如使用以下方法:
Async.RunSynchronously(Async.Sleep 3000, cancellationToken = tok)
但我想在这里等待只是出于提问的目的,您实际上正在执行一些其他(可能是可取消的,可能不是)操作。如果您在异步计算中使用CancellationToken
,异步工作流将自动传播它,以便您可以在任何地方访问它,但您仍然需要明确检查取消是否已触发,并自己抛出异常。这不会在同步用户代码的任何地方“自动”发生
这意味着问题有两个部分。1) 如何访问取消令牌以及2)如何检查其是否已被取消
第二部分有点棘手,因为您需要使用Async.CancellationToken
,但这会返回Async
,因此您必须在FromContinuations
代码之外的异步块中调用它。第二部分只是调用代码中的某个地方的tok.throwifcancellationrequest()
在执行除名之前,检查是否取消:
let asyncComputation divisor = async {
let! tok = Async.CancellationToken
return! Async.FromContinuations
(fun (success, except, cancel) ->
try
printfn "Going to sleep..."
Threading.Thread.Sleep 3000
printfn "...waking up"
tok.ThrowIfCancellationRequested()
1 / divisor |> ignore
printfn "Calling success continuation..."
success ()
with
| :? OperationCanceledException as e ->
printfn "Calling cancellation continuation..."
cancel e
| e ->
printfn "Calling exception continuation..."
except e) }
这不会在等待时取消。如果需要,您需要能够取消等待操作,例如使用以下方法:
Async.RunSynchronously(Async.Sleep 3000, cancellationToken = tok)
但我想在这里等待只是为了提问,而实际上您正在执行一些其他(可能是可取消的,可能不是)操作