我对 Swift 中的
async
/await
概念还很陌生。所以我给自己开发了一个小游乐场:
import Foundation
func dummyLoop() async {
print("inside dummy fcn")
for i in 0 ..< 10 {
if Task.isCancelled {
return
}
print("Loop \(i)")
try? await Task.sleep(for: .seconds(1))
}
}
let task = Task(priority: .high) {
await dummyLoop()
}
print("Press any key to stop task...")
_ = readLine()
task.cancel()
print("Press any key to stop finish app...")
_ = readLine()
print("Ciao")
所以我想运行一些虚拟循环并在控制台中按 Enter 后停止它。但我看到任务关闭根本没有执行。我发现这种行为在某种程度上与
RunLoop
有关...有人可以解释一下这里发生了什么吗?我应该如何运行 Task
在控制台应用程序中并行执行?
Task.init
继承参与者上下文,在本例中是主要参与者。主要参与者在主线程上运行,但主线程被 readLine
阻塞,因此什么也做不了。
您可以使用
Task.detached
来代替,它在协作线程池中的某个线程上运行任务。
let task = Task.detached(priority: .high) {
await dummyLoop()
}
或者,您可以从 stdin 异步读取,而不是使用会阻塞的
readLine
。
var iterator = FileHandle.standardInput.bytes.lines.makeAsyncIterator()
print("Press any key to stop task...")
_ = try await iterator.next()
task.cancel()
print("Press any key to stop finish app...")
_ = try await iterator.next()
print("Ciao")
在打印消息中,您提到“按任意键...”,但是
readLine
和异步读取行都无法实现这一点。无论哪种情况,程序都会等待返回键。要检测任何按键,您可以使用这篇文章中的
enableRawMode
。