Swift并发:如何保证任务按顺序执行?
在Swift Concurrency中保证任务执行顺序的几种方式
你原来的GCD代码能正常工作,核心是同一个串行DispatchQueue会按任务提交顺序执行:先跑async的append操作,再执行sync的遍历检查,自然能读到刚添加的值。在Swift Concurrency里,有几种更贴合新并发模型的实现方式:
方式一:显式等待异步任务完成
直接用await等待第一个异步任务结束,再执行后续逻辑,这是最直观的写法:
var exampleList = [String]() // 启动异步任务并保存Task实例 let appendTask = Task { exampleList.append("Hello") } // 等待异步任务执行完成 await appendTask.value // 此时append操作已完成,执行检查逻辑 for item in exampleList { if item == "Hello" { print("list contains hello") } }
⚠️ 注意:如果exampleList会被多个任务同时访问,上面的写法存在线程安全问题,建议用下面的Actor方式解决。
方式二:用Actor实现串行执行(对应GCD串行队列)
Actor是Swift Concurrency的核心组件,它内部的所有方法都会串行执行,完美对应GCD串行队列的特性,同时还自动保证线程安全:
// 用Actor封装列表操作,确保所有访问都是串行且线程安全的 actor ListManager { private var exampleList = [String]() // 添加元素的方法 func appendItem(_ item: String) { exampleList.append(item) } // 检查元素的方法 func checkForHello() { if exampleList.contains("Hello") { print("list contains hello") } } } // 使用示例 let listManager = ListManager() // 先提交添加任务,再提交检查任务 await listManager.appendItem("Hello") await listManager.checkForHello() // 或者用Task分别提交,Actor会自动按顺序执行 Task { await listManager.appendItem("Hello") } Task { await listManager.checkForHello() }
不管是连续await还是用两个Task提交,Actor都会保证appendItem执行完成后才会运行checkForHello,和你原来的GCD逻辑完全一致。
为什么AsyncChannel不适合你的场景
AsyncChannel主要用于事件流传递(比如一次性或多次发送事件给消费者),但你的需求是保证任务的执行顺序,用await显式等待或Actor串行执行的方式更直接,不需要额外的事件传递逻辑。
内容的提问来源于stack exchange,提问作者Shape Fit
相关产品推荐
相关产品推荐

