Bird
Raised Fist0
Swiftprogramming~5 mins

Cancellation handling in Swift

Choose your learning style10 modes available
Introduction

Cancellation handling lets your program stop a task that is no longer needed. This saves time and resources.

When a user closes a screen and you want to stop loading data.
When a network request is taking too long and you want to cancel it.
When a background task is no longer relevant because the user changed their mind.
When you want to stop a long-running operation to keep the app responsive.
Syntax
Swift
Task {
    do {
        try Task.checkCancellation()
        // Your work here
    } catch {
        // Handle cancellation here
    }
}

Task.checkCancellation() throws an error if the task was cancelled.

Use Task.isCancelled to check cancellation without throwing.

Examples
This example checks for cancellation in a loop and stops if cancelled.
Swift
Task {
    do {
        for i in 1...5 {
            try Task.checkCancellation()
            print("Working on step \(i)")
            try await Task.sleep(nanoseconds: 500_000_000) // 0.5 seconds
        }
        print("Task completed")
    } catch {
        print("Task was cancelled")
    }
}
This example uses Task.isCancelled to stop a loop when cancelled.
Swift
let task = Task {
    while !Task.isCancelled {
        print("Running...")
        try await Task.sleep(nanoseconds: 1_000_000_000) // 1 second
    }
    print("Task stopped because it was cancelled")
}

// Later in code
// task.cancel() to stop the task
Sample Program

This program starts a task that prints steps with delays. After 1 second, it cancels the task. The task stops early and prints a cancellation message.

Swift
import Foundation

let task = Task {
    do {
        for i in 1...10 {
            try Task.checkCancellation()
            print("Step \(i)")
            try await Task.sleep(nanoseconds: 300_000_000) // 0.3 seconds
        }
        print("All steps done")
    } catch {
        print("Task was cancelled")
    }
}

// Cancel the task after 1 second
Task {
    try await Task.sleep(nanoseconds: 1_000_000_000)
    task.cancel()
}

// Keep the main thread alive to see output
RunLoop.main.run(until: Date().addingTimeInterval(2))
OutputSuccess
Important Notes

Always check for cancellation regularly in long tasks to stop quickly.

Cancellation throws a special error, so use try/catch to handle it.

Calling task.cancel() only requests cancellation; the task must check and stop itself.

Summary

Cancellation handling helps stop tasks that are no longer needed.

Use Task.checkCancellation() or Task.isCancelled to detect cancellation.

Handle cancellation with try/catch to keep your app responsive and efficient.

Practice

(1/5)
1. What is the main purpose of cancellation handling in Swift concurrency?
easy
A. To create new tasks continuously
B. To speed up all running tasks
C. To restart tasks automatically
D. To stop tasks that are no longer needed

Solution

  1. Step 1: Understand cancellation handling concept

    Cancellation handling is used to stop tasks that are no longer needed to save resources.
  2. Step 2: Compare options with concept

    Only To stop tasks that are no longer needed matches the purpose of stopping unnecessary tasks.
  3. Final Answer:

    To stop tasks that are no longer needed -> Option D
  4. Quick Check:

    Cancellation handling = stop unnecessary tasks [OK]
Hint: Cancellation means stopping tasks early to save resources [OK]
Common Mistakes:
  • Thinking cancellation speeds up tasks
  • Confusing cancellation with restarting tasks
  • Assuming cancellation creates new tasks
2. Which of the following is the correct way to check for cancellation inside a Swift async task?
easy
A. if Task.cancelled() { return }
B. if Task.isCancelled { return }
C. if Task.checkCancel() { return }
D. if Task.isCancel { return }

Solution

  1. Step 1: Recall correct API for cancellation check

    The correct property to check cancellation is Task.isCancelled.
  2. Step 2: Verify syntax correctness

    if Task.isCancelled { return } uses Task.isCancelled correctly; others use invalid method or property names.
  3. Final Answer:

    if Task.isCancelled { return } -> Option B
  4. Quick Check:

    Use Task.isCancelled to check cancellation [OK]
Hint: Remember: Task.isCancelled is a property, not a method [OK]
Common Mistakes:
  • Using incorrect method names like cancelled()
  • Confusing property names with similar words
  • Missing capitalization or spelling errors
3. What will be the output of the following Swift code snippet?
Task {
    for i in 1...3 {
        try Task.checkCancellation()
        print("Running step \(i)")
        if i == 2 {
            Task.current.cancel()
        }
    }
}
medium
A. Running step 1 Running step 2
B. Running step 1 Running step 2 Running step 3
C. Running step 1
D. No output due to immediate cancellation

Solution

  1. Step 1: Understand Task.checkCancellation() behavior

    Task.checkCancellation() throws if the task is cancelled, stopping further execution.
  2. Step 2: Analyze loop and cancellation timing

    Cancellation happens when i == 2, so steps 1 and 2 print, but step 3 is skipped due to cancellation.
  3. Final Answer:

    Running step 1\nRunning step 2 -> Option A
  4. Quick Check:

    Cancellation after step 2 stops step 3 [OK]
Hint: Cancellation stops loop after current iteration [OK]
Common Mistakes:
  • Assuming all steps run despite cancellation
  • Ignoring that checkCancellation throws on cancel
  • Thinking cancellation happens before step 2
4. Identify the error in this Swift async task cancellation handling code:
Task {
    if Task.isCancelled {
        print("Cancelled")
    }
    try Task.checkCancellation()
    print("Running")
}
medium
A. Task.isCancelled check is redundant before checkCancellation()
B. Missing try keyword before Task.checkCancellation()
C. No error; code handles cancellation correctly
D. Task.isCancelled should be checked after checkCancellation()

Solution

  1. Step 1: Understand difference between Task.isCancelled and checkCancellation()

    Task.checkCancellation() throws if cancelled, so it already handles cancellation detection.
  2. Step 2: Analyze redundancy of Task.isCancelled check

    Checking Task.isCancelled before checkCancellation() is redundant because checkCancellation() will throw if cancelled.
  3. Final Answer:

    Task.isCancelled check is redundant before checkCancellation() -> Option A
  4. Quick Check:

    checkCancellation() alone suffices to detect cancellation [OK]
Hint: Use checkCancellation() to handle cancellation, no need for isCancelled first [OK]
Common Mistakes:
  • Thinking isCancelled must come before checkCancellation()
  • Missing try keyword (actually present here)
  • Assuming no error when redundancy exists
5. You want to cancel a long-running Swift async task when a user taps a cancel button. Which approach correctly handles cancellation and cleans up resources?
func performTask() async {
    let task = Task {
        do {
            for i in 1...5 {
                try Task.checkCancellation()
                print("Processing \(i)")
                try await Task.sleep(nanoseconds: 1_000_000_000)
            }
        } catch {
            print("Task was cancelled")
        }
        print("Cleanup done")
    }
    // User taps cancel button
    task.cancel()
}
hard
A. Task.cancel() should be called inside the task, not outside
B. Cleanup code will not run after cancellation
C. This code correctly cancels the task and runs cleanup after cancellation
D. Task.checkCancellation() does not throw, so cancellation is ignored

Solution

  1. Step 1: Analyze cancellation handling in the task

    Task.checkCancellation() throws when cancelled, caught by catch block which prints cancellation message.
  2. Step 2: Verify cleanup code execution

    Cleanup code runs after catch block, ensuring resources are cleaned up even after cancellation.
  3. Final Answer:

    This code correctly cancels the task and runs cleanup after cancellation -> Option C
  4. Quick Check:

    Cancellation triggers catch and cleanup runs [OK]
Hint: Use try/catch with checkCancellation() to handle cancel and cleanup [OK]
Common Mistakes:
  • Assuming cleanup won't run after cancellation
  • Calling cancel() inside the task incorrectly
  • Believing checkCancellation() does not throw
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard