首页 > 解决方案 > 在串行队列中同步异步任务

问题描述

let serialQueue = DispatchQueue(label: "Serial Queue")
func performCriticalSectionTask() {
 serialQueue.async {
   performLongRuningAsyncTask()
 }
}

func performLongRuningAsyncTask() {
  /// some long running task
}

该函数performCriticalSectionTask()可以从不同的地方多次调用。我希望这个函数一次运行一个。因此,我将代码的关键部分保留在串行异步队列中。

但是,这里的问题是临界区本身是一个performLongRuningAsyncTask()会立即返回的,因此serial queue不会等待当前任务首先完成,而是会启动另一个。

我怎么解决这个问题?

标签: iosswiftgrand-central-dispatch

解决方案


如果performLongRuningAsyncTask只在一个线程中运行,那么它一次只会被调用一次。在您的情况下,它将它委托给另一个线程,因此您将其包装到另一个线程调用中不起作用,因为它无论如何都会在另一个线程上

您可以在方法本身中进行检查,最简单的方法是添加一个布尔值。(或者您可以使用完成处理程序在执行此方法的类中添加这些检查)。另一种方法是添加调度组/信号量/锁。如果以后还需要执行,应该使用调度组/OperationQueue/Semaphore。

func performLongRunningAsyncTask() {
   self.serialQueue.sync {
       if isAlreadyRunning {
          return 
       }

       isAlreadyRunning = true
   }

   asyncTask { result in 

     self.serialQueue.sync {
        self.isAlreadyRunning = false
     }
   }
}

推荐阅读