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