let serialQueue = DispatchQueue(label: "Serial Queue")
func performCriticalSectionTask() {
serialQueue.async {
performLongRuningAsyncTask()
}
}
func performLongRuningAsyncTask() {
/// some long running task
}
函数performCriticalSectionTask()
可以从不同的地方被多次调用。我希望这个函数一次运行一个。因此,我将代码的关键部分保留在串行异步队列中。
但是,这里的问题是,关键部分本身是一个performLongRuningAsyncTask()
,它将立即返回,因此serial queue
不会等待当前任务首先完成,而是开始另一个任务。
我该如何解决这个问题?
如果performLongRuningAsyncTask
只在一个线程中运行,则一次只调用一次。在你的情况下,它将它委托给另一个线程,所以你将它包装到另一个调用中是不起作用的,因为它无论如何都会在另一个线程上
您可以在方法本身中进行检查,最简单的方法是添加布尔值。(或者,您可以在执行此方法的类中添加这些检查,并使用完成处理程序(。另一种方法是添加调度组/信号量/锁。如果以后仍需要执行它,则应该使用调度组/OperationQueue/Ssemaphore。
func performLongRunningAsyncTask() {
self.serialQueue.sync {
if isAlreadyRunning {
return
}
isAlreadyRunning = true
}
asyncTask { result in
self.serialQueue.sync {
self.isAlreadyRunning = false
}
}
}