简体   繁体   中英

Dispatch queue blocks main thread

I have multiple tasks that I want to put in a serial/concurrent queue running in background thread. Each of the tasks will fetch data from api(async) then copyItem (sync, depends on the res of fetch ). The code below blocks main thread. However main thread will not be blocked if I only assign copyItem to the queue. Why can't I run the whole block in background thread ?

let serialQueue = DispatchQueue(label: "queue", qos: .background)
tableView.selectedRowIndexes.forEach { row in

  serialQueue.async {   

    InitData.fetch("someUrl") { initData in
      let fileManager = FileManager()                
      do {
         try fileManager.copyItem(atPath: "pathA", toPath: "pathB")
      } catch let error {
         print(error)
      }
    }
  }
}

This doesn't block main thread:

tableView.selectedRowIndexes.forEach { row in

  InitData.fetch("someUrl") { initData in
    let fileManager = FileManager()
    let workItem = DispatchWorkItem {          
      do {
        try fileManager.copyItem(atPath: "pathA", toPath: "pathB")
      } catch let error {
        print(error)
      }
    }
    DispatchQueue.global(qos: .background).async(execute: workItem)
  }
}

We can deduce from your symptoms that InitData.fetch takes two arguments: a string ( "someUrl" ) and a callback, and that it submits the callback to the main queue for execution. It doesn't matter what queue you were on when you called InitData.fetch . What matters is the queue that InitData eventually (asynchronously) uses to schedule execution of the callback. Maybe you can tell it which queue you want it to use, but apparently in the program you've written, it uses the main queue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM