ArgumentParser中AsyncParsableCommand无法识别async run()函数
问题分析与解决方案
核心问题1:run()方法签名不匹配
你给run()加了mutating修饰符,但AsyncParsableCommand协议定义的run()方法是非mutating的异步方法。当签名不匹配时,系统会执行协议的默认实现(打印命令帮助),而非你的自定义逻辑。
核心问题2:异步任务未被等待
即使修复签名,你的doAsyncInLoop里启动了独立Task后直接返回,导致run()执行完就退出程序,异步任务还没完成就被终止。
修复步骤
1. 移除run()的mutating修饰符
修改后的run()方法:
func run() async throws { print("In \(#function). count == \(count ?? 0)") if let count, count > 0 { await doAsyncInLoop(count: count) } }
2. 等待异步任务完成
将doAsyncInLoop里的嵌套Task移除,直接在方法内执行循环并等待每个任务:
func doAsyncInLoop(count: Int) async { if #available(macOS 10.15, *) { print("In macOS ≥10.15") for index in 1...count { do { let result = try await doAsyncTask(index: index) print(result) } catch { print("Async job \(index) failed: \(error)") } } } else { print("In macOS <10.15. Task() not available.") } }
完整修复后的代码
import ArgumentParser import Foundation @main struct AsyncTest: AsyncParsableCommand { @Option(name: .shortAndLong, help: "The number of times to snork.") var count: Int? = nil func doAsyncInLoop(count: Int) async { if #available(macOS 10.15, *) { print("In macOS ≥10.15") for index in 1...count { do { let result = try await doAsyncTask(index: index) print(result) } catch { print("Async job \(index) failed: \(error)") } } } else { print("In macOS <10.15. Task() not available.") } } @discardableResult func doAsyncTask(index: Int) async throws -> String { print("In \(#function).") let millisecond = NSEC_PER_SEC / 1000 let duration = millisecond * UInt64.random(in: 10...500) if #available(macOS 10.15, *) { try await Task.sleep(nanoseconds: duration) } return "Async job \(index) complete" } func run() async throws { print("In \(#function). count == \(count ?? 0)") if let count, count > 0 { await doAsyncInLoop(count: count) } } }
验证修复
运行命令:
swift run AsyncTest --count 3
此时程序会依次执行3个异步任务,等待每个任务完成后输出结果,所有任务结束后才会退出。
内容的提问来源于stack exchange,提问作者Duncan C
相关产品推荐
相关产品推荐

