2025-02-08 12:24:31
,某些文章具有时效性,若有错误或已失效,请在下方留言。Every task can be created with a specific priority level, or it can inherit a priority from somewhere else. But in two specific circumstances, Swift will raise the priority of a task so it’s able to complete faster.
每个任务都可以使用特定的优先级创建,也可以从其他位置继承优先级。但在两种特定情况下,Swift 会提高任务的优先级,以便它能够更快地完成。
This always happens because of some specific action from us. For example, if high-priority task A starts waiting for the result of low-priority task B, task B will have its priority elevated to the same priority as task A.
这总是因为我们的一些特定行动而发生的。例如,如果高优先级任务 A 开始等待低优先级任务 B 的结果,则任务 B 的优先级将提升到与任务 A 相同的优先级。
You can see this for yourself with a little code:
您可以通过一些代码亲自看到这一点:
@main
struct App {
static func main() async throws {
// Create a high-priority task
let outerTask = Task(priority: .high) {
print("Outer: \(Task.currentPriority)")
// Create a nested, low-priority task inside there.
let innerTask = Task(priority: .low) {
print("Inner: \(Task.currentPriority)")
try await Task.sleep(for: .seconds(1))
print("Inner: \(Task.currentPriority)")
}
// Make the high-priority task wait for its low-priority child
try await Task.sleep(for: .seconds(0.5))
_ = try await innerTask.value
}
// Wait for the whole thing to finish
_ = try await outerTask.value
}
}
Here we have a high-priority task using await
on a low-priority task, and so you’ll see the inner task’s priority will report low
initially, then move up to report high
as soon as the outer task starts waiting for it – Task.currentPriority
will report the escalated priority rather than the original priority.
在这里,我们有一个高优先级任务,在低优先级任务上使用 await
,因此你会看到内部任务的优先级最初会报告为低
,然后在外部任务开始等待它时立即上升到报告高
– Task.currentPriority
将报告升级的优先级,而不是原始优先级。
The other place this happens is when low-priority task A has started running on an actor, and high-priority task B has been enqueued on that same actor, task A will have its priority elevated to match task B to avoid creating a jam.
发生这种情况的另一个情况是,当低优先级任务 A 开始在 Actor 上运行,并且高优先级任务 B 已在同一 Actor 上排队时,任务 A 的优先级将提升以匹配任务 B,以避免产生阻塞。
In both cases, Swift is trying to ensure the higher priority task gets the quality of service it needs to run quickly – if something very important can only complete when something less important is also complete, then the less important task becomes very important.
在这两种情况下,Swift 都试图确保高优先级任务获得快速运行所需的服务质量 – 如果非常重要的事情只有在不太重要的事情也完成时才能完成,那么不太重要的任务就会变得非常重要。
For the most part, priority escalation isn’t something we need to worry about in our code – think of it as a bonus feature provided automatically by Swift’s tasks.
在大多数情况下,优先级提升并不是我们在代码中需要担心的事情 – 可以将其视为 Swift 任务自动提供的附加功能。
At the time of writing, this is the only real “gotcha” moment with task escalation. The other situation – if you queue a high-priority task on the same actor where a low-priority task is already running – will also involve priority escalation, but won’t change the value of currentPriority
. This means your task will run a little faster and it might not be obvious why, but honestly it’s unlikely you’ll even notice this.
在撰写本文时,这是任务升级唯一真正的“陷阱”时刻。另一种情况 – 如果您在低优先级任务已经在运行的同一 actor 上将高优先级任务排队 – 也将涉及优先级提升,但不会更改 currentPriority
的值。这意味着你的任务会运行得更快一些,原因可能并不明显,但老实说,你甚至不太可能注意到这一点。