Tailwind CSSTailwind CSS
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
  • Task优先级与取消

Task优先级与取消

在Swift并发中,Task不仅是一个异步任务的执行容器,还提供了优先级控制和取消功能,让开发者能够更精细地管理任务的执行顺序和生命周期。前一节介绍了Task的基本创建与管理,本节将聚焦于Task的优先级设置和取消操作,讲解其工作原理、使用场景及最佳实践。通过这些知识,你将能优化任务调度并处理用户中断需求。

Task优先级

Swift允许通过priority参数为Task指定执行优先级,影响其在底层GCD线程池中的调度顺序。优先级设置并非强制执行,而是系统根据资源可用性和其他任务的竞争进行调整。

优先级选项

TaskPriority枚举提供了以下常见值:

  • .userInitiated:用户触发的紧急任务(如按钮点击),高优先级。
  • .high:重要但非交互的任务。
  • .default:默认优先级,适用于大多数情况。
  • .utility:中等优先级,适合次要操作。
  • .background:最低优先级,用于后台任务(如日志同步)。

示例:

func processData() async -> String {
    try? await Task.sleep(nanoseconds: 1_000_000_000)
    return "处理完成"
}

Task(priority: .userInitiated) {
    let result = await processData()
    print("高优先级:\(result) - \(Task.currentPriority.rawValue)")
}

Task(priority: .background) {
    let result = await processData()
    print("低优先级:\(result) - \(Task.currentPriority.rawValue)")
}

输出可能为:

高优先级:处理完成 - 25
低优先级:处理完成 - 9
  • Task.currentPriority:检查当前任务的优先级(数值越高,优先级越高)。

优先级继承

子任务会继承父任务的优先级,除非显式指定:

Task(priority: .high) {
    print("父任务优先级:\(Task.currentPriority.rawValue)")
    Task {
        print("子任务继承优先级:\(Task.currentPriority.rawValue)")
    }
    Task(priority: .background) {
        print("子任务覆盖优先级:\(Task.currentPriority.rawValue)")
    }
}

输出:

父任务优先级:21
子任务继承优先级:21
子任务覆盖优先级:9
  • 未指定优先级的子任务继承父级。
  • 显式指定会覆盖继承。

使用场景

  • 用户交互:.userInitiated确保快速响应。
  • 批量处理:.utility或.background避免抢占主线程。
  • 混合任务:不同优先级区分重要性。

Task取消

Task支持取消操作,通过cancel()方法通知任务停止。取消是一种协作机制,任务需主动检查并响应。

基本取消

调用cancel()并检查isCancelled:

let task = Task {
    for i in 1...5 {
        try? await Task.sleep(nanoseconds: 500_000_000)
        guard !Task.isCancelled else {
            print("任务已取消")
            return
        }
        print("进度:\(i)")
    }
    print("任务完成")
}

Task {
    try? await Task.sleep(nanoseconds: 1_500_000_000)
    task.cancel()
}

输出:

进度:1
进度:2
进度:3
任务已取消
  • isCancelled:布尔值,表示任务是否被取消。
  • 开发者需在逻辑中检查并退出。

取消传播

父任务取消时,子任务自动收到通知:

let parentTask = Task {
    Task {
        try? await Task.sleep(nanoseconds: 2_000_000_000)
        guard !Task.isCancelled else {
            print("子任务取消")
            return
        }
        print("子任务完成")
    }
    try? await Task.sleep(nanoseconds: 1_000_000_000)
    print("父任务运行")
}

Task {
    try? await Task.sleep(nanoseconds: 500_000_000)
    parentTask.cancel()
}

输出:

父任务运行
子任务取消
  • 父任务取消后,子任务的isCancelled变为true。
  • 需显式检查,未检查的任务继续运行。

抛出取消错误

Swift提供CancellationError,可在检查时抛出:

let cancellableTask = Task {
    for i in 1...5 {
        try await Task.sleep(nanoseconds: 500_000_000)
        try Task.checkCancellation() // 抛出CancellationError
        print("进度:\(i)")
    }
}

Task {
    try? await Task.sleep(nanoseconds: 1_000_000_000)
    cancellableTask.cancel()
    do {
        try await cancellableTask.value
    } catch {
        print("任务取消:\(error)")
    }
}

输出:

进度:1
任务取消:CancellationError()
  • checkCancellation():若已取消,抛出错误,简化逻辑。

实际应用

1. 用户中断

响应用户取消操作:

class DownloadViewController: UIViewController {
    var downloadTask: Task<Void, Never>?

    @IBAction func startDownload(_ sender: UIButton) {
        downloadTask = Task {
            for i in 1...10 {
                try? await Task.sleep(nanoseconds: 1_000_000_000)
                guard !Task.isCancelled else { return }
                await MainActor.run { progressLabel.text = "进度:\(i)0%" }
            }
            await MainActor.run { progressLabel.text = "完成" }
        }
    }

    @IBAction func cancelDownload(_ sender: UIButton) {
        downloadTask?.cancel()
        progressLabel.text = "已取消"
    }
}
  • 高优先级任务响应用户点击。

2. 优先级调度

优化多任务执行:

Task(priority: .userInitiated) {
    let data = await fetchCriticalData()
    print("关键数据:\(data)")
}

Task(priority: .background) {
    let log = await syncLogs()
    print("日志同步:\(log)")
}
  • 关键任务优先执行。

最佳实践

  1. 合理设置优先级
    避免所有任务都用.high,会导致优先级失效。

  2. 及时检查取消
    在循环或耗时操作中定期检查isCancelled。

  3. 清理资源
    取消后释放占用资源(如网络连接)。

  4. 日志记录
    记录取消事件,便于调试:

    if Task.isCancelled { print("任务\(task.id)取消") }
    

小结

Task的优先级和取消功能为异步任务管理提供了灵活性。优先级控制任务调度顺序,取消机制响应中断需求。本节通过示例展示了其用法和应用场景,强调了协作取消的重要性。掌握这些技巧,你将能优化任务执行并处理动态需求。下一节将探讨结构化并发,进一步提升你的并发设计能力。


内容说明

  • 结构:从优先级到取消,再到应用和实践,最后总结。
  • 代码:包含优先级、取消和UI示例,突出实用性。
  • 语气:深入且实践导向,适合技术书籍深入章节。
  • 衔接:承接前节(Task基础),预告后续(结构化并发)。
Last Updated:: 3/4/25, 10:21 AM