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)
但我想在这里等待只是为了提问,而实际上您正在执行一些其他(可能是可取消的,可能不是)操作