Swift中如何按顺序执行Actor异步方法并等待条件满足
解决方案:按顺序执行Actor的异步方法
你的核心问题在于当前的asyncForEach使用了TaskGroup,会并行启动所有任务,导致Actor的bar()方法同时执行,无法保证顺序。要实现顺序执行,不需要用复杂的条件锁,利用Swift async/await的特性就能轻松解决,下面提供两种简洁的方案:
方案一:修改asyncForEach为顺序执行版本
直接去掉TaskGroup,遍历序列时逐个await操作,自然就能保证顺序执行:
extension Sequence { func asyncForEachOrdered(_ operation: @escaping (Element) async throws -> Void) async throws { for element in self { try await operation(element) } } }
在foo()中调用这个修改后的方法即可:
func foo() async throws { let actorsAndOrders: [Int: ProtocolConformingActors] = [1: actor1, 2: actor2, 3: actor3] // 获取排序后的执行顺序 let orders = actorsAndOrders.keys.sorted() // 按顺序执行每个Actor的bar()方法 try await orders.asyncForEachOrdered { order in guard let actor = actorsAndOrders[order] else { return } try await actor.bar() } }
方案二:直接使用普通for循环(更简洁)
其实不需要额外的扩展,直接在foo()里用普通for循环遍历排序后的订单,逐个await就能保证顺序:
func foo() async throws { let actorsAndOrders: [Int: ProtocolConformingActors] = [1: actor1, 2: actor2, 3: actor3] // 获取排序后的执行顺序 let orders = actorsAndOrders.keys.sorted() // 前一个bar()执行完成后,才会启动下一个 for order in orders { guard let actor = actorsAndOrders[order] else { continue } try await actor.bar() } }
为什么你的NSCondition方案没生效?
Actor本身是线程安全的隔离环境,而NSCondition是基于Objective-C的传统锁机制,在Swift Concurrency环境下混用容易出现线程冲突或等待逻辑失效的问题。Swift Concurrency推荐用自身的结构化并发特性(比如顺序await、TaskGroup的依赖控制)处理同步问题,而非传统锁。
内容的提问来源于stack exchange,提问作者Tiny Tim
相关产品推荐
相关产品推荐

