/*:#localized(key: "WhatCancellationIsNot")
 # What cancellation is *not*

 The single biggest cancellation bug is assuming `cancel()` *did* something. It
 didn't, not on its own. Watch a task that never checks simply ignore it:
 */
//#-editable-code
import Foundation
import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true

// A plain (synchronous) function that blocks: no await inside.
func stubbornStep(_ step: Int) {
    Thread.sleep(forTimeInterval: 0.2)   // blocking work, not a suspension
    print("Stubborn step \(step)")
}

let stubborn = Task {
    for step in 1...5 {
        // Never checks isCancelled or checkCancellation, never looks.
        stubbornStep(step)
    }
    print("Stubborn task finished all 5 steps")
    PlaygroundPage.current.finishExecution()
}

stubborn.cancel()   // marks it cancelled... and nothing happens
//#-end-editable-code
/*:#localized(key: "WhatCancellationIsNot-2")
 **Watch it run:** all five steps print, then "finished all 5 steps," even
 though you cancelled it before it began. `cancel()` set the flag; the loop
 never read the flag; the work ran to completion.

 It uses `Thread.sleep` on purpose, blocking, not `await`, so there's no
 suspension point to even notice the cancellation. Swift 6 won't let you call
 `Thread.sleep` directly inside an async task, which is exactly why it lives
 in the plain `stubbornStep` function here.

 * Cancellation is **not** a forced stop, a kill, or a `throw` injected into
 your code.
 * Cancellation is **ignored** entirely if your work never checks for it.
 * Long-running loops and any code that does real work between `await`s should
 check cancellation periodically; otherwise "cancel" is a lie.

 [Previous](@previous)  |  page 9 of 11  |  [Next: Priorities and Yielding](@next)
 */
