【问题标题】:Cooperative cancellation in F# with cancel continuationF# 中的合作取消与取消继续
【发布时间】:2016-10-02 10:27:44
【问题描述】:

可能我这里有 2 个问题而不是 1 个,但无论如何。

我正在以here suggested 的身份实施合作取消。这是我的测试代码:

type Async with
    static member Isolate(f : CancellationToken -> Async<'T>) : Async<'T> =
        async {
            let! ct = Async.CancellationToken
            let isolatedTask = Async.StartAsTask(f ct)
            return! Async.AwaitTask isolatedTask
        }

let testLoop (ct: CancellationToken) = async {
    let rec next ix =
        if ct.IsCancellationRequested then ()
        else 
            printf "%i.." ix
            Thread.Sleep 10  
            next (ix+1)
    next 1
}

let cancellationSource = new CancellationTokenSource()
let onDone () = printfn "!! DONE"
let onError _ = printfn "!! ERROR"
let onCancel _ = printfn "!! CANCEL"

Async.StartWithContinuations (Async.Isolate testLoop, onDone, onError, onCancel, cancellationSource.Token)

Thread.Sleep(100)
cancellationSource.Cancel ()
Thread.Sleep(500)

如您所见,我从 donecancelerror 延续开始异步。如果我按原样运行该代码,我将得到以下输出:

1..2..3..4..5..6..7..8..!!完成

如果我稍微更新Isolate方法如下:

    static member Isolate(f : CancellationToken -> Async<'T>) : Async<'T> =
        async {
            let! ct = Async.CancellationToken
            let isolatedTask = Async.StartAsTask(f ct)
            let! x = Async.AwaitTask isolatedTask
            x
        }

我得到了预期的(自己)输出:

1..2..3..4..5..6..7..!!取消

为什么我们的行为会有如此不同?

如果testLoop 没有在某个超时时间内取消,是否可以中止它?

【问题讨论】:

    标签: asynchronous f# cancellation


    【解决方案1】:

    async 块仅在绑定之前和之后检查Async.CancellationToken 的取消(使用let! 编写)。这意味着当令牌被取消时,工作流只会在有更多工作要做时才会被取消。

    还值得注意的是,isolatedTask 在此示例中本身并没有被取消,因为它只是定期终止(使用 if)。

    在你的情况下:

    • 当您仅使用 return! 时,任务会定期返回,Async.AwaitTask 会定期返回,之后什么都不做,因此工作流程完成。

    • 当您使用let! 后跟return 时,任务会定期返回,Async.AwaitTask 会定期返回,但随后let! 在运行return 之前检查取消之前 和这将取消工作流。

    【讨论】:

      猜你喜欢
      • 2012-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-27
      • 1970-01-01
      相关资源
      最近更新 更多