同步串行队列中的异步任务

问题描述

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
     }
   }
}