Swift - async/await - 在 MainActor 任务的后台线程上执行异步方法
Swift - async/await - Execute async method on background thread from MainActor Task
这是我的 viewDidLoad
方法:
func viewDidLoad() {
// Stuff here
Task { @MainActor in
doSomeWorkOnMainThread1()
doSomeWorkOnMainThread2()
await doSomeBackgroundWork()
doSomeWorkOnMainThread3()
doSomeWorkOnMainThread4()
}
}
这是我的方法,应该在后台线程上执行工作:
func doSomeBackgroundWork() async {
// can add some code here
// long image processing task
assert(!Thread.isMainThread)
// can add some code here
}
是否可以在后台线程(不使用 GCD)上执行 doSomeBackgroundWork
,然后等待它返回主线程?
您正在寻找 Task.sleep。请注意,它以纳秒为单位,这真的很奇怪,所以我写了一个扩展来切换到秒;要得到它,你必须使用 Double,而不是 Int:
extension Task where Success == Never, Failure == Never {
static func sleep(_ seconds:Double) async {
await self.sleep(UInt64(seconds * 1_000_000_000))
}
static func sleepThrowing(_ seconds:Double) async throws {
try await self.sleep(nanoseconds: UInt64(seconds * 1_000_000_000))
}
}
保证一项工作将在后台线程上完成的方法是将该工作交给 Actor。这就是 Actor 的用途(部分)。
例如,如果一个 Actor 有一个调用 Task.sleep
的方法 doSleep
,那么如果您实例化该 actor 并从您的任务调用该方法,它将在后台线程中休眠。
此解决方案有效,但我猜它并不完美:
func doSomeBackgroundWork() async {
await Task {
// long image processing task
assert(!Thread.isMainThread)
}.result
}
这是我的 viewDidLoad
方法:
func viewDidLoad() {
// Stuff here
Task { @MainActor in
doSomeWorkOnMainThread1()
doSomeWorkOnMainThread2()
await doSomeBackgroundWork()
doSomeWorkOnMainThread3()
doSomeWorkOnMainThread4()
}
}
这是我的方法,应该在后台线程上执行工作:
func doSomeBackgroundWork() async {
// can add some code here
// long image processing task
assert(!Thread.isMainThread)
// can add some code here
}
是否可以在后台线程(不使用 GCD)上执行 doSomeBackgroundWork
,然后等待它返回主线程?
您正在寻找 Task.sleep。请注意,它以纳秒为单位,这真的很奇怪,所以我写了一个扩展来切换到秒;要得到它,你必须使用 Double,而不是 Int:
extension Task where Success == Never, Failure == Never {
static func sleep(_ seconds:Double) async {
await self.sleep(UInt64(seconds * 1_000_000_000))
}
static func sleepThrowing(_ seconds:Double) async throws {
try await self.sleep(nanoseconds: UInt64(seconds * 1_000_000_000))
}
}
保证一项工作将在后台线程上完成的方法是将该工作交给 Actor。这就是 Actor 的用途(部分)。
例如,如果一个 Actor 有一个调用 Task.sleep
的方法 doSleep
,那么如果您实例化该 actor 并从您的任务调用该方法,它将在后台线程中休眠。
此解决方案有效,但我猜它并不完美:
func doSomeBackgroundWork() async {
await Task {
// long image processing task
assert(!Thread.isMainThread)
}.result
}