0

I have an async function with a completionHandler (let's say it's called asyncFunction) that I'm calling inside another function. I want this second function to wait for the async function. So, basically I want this second function to be run synchronously. I'm using DispatchGroup and wait(), but it looks like there's a deadlock. It waits forever.

Here's what I'm doing.

let dispatchGroup = DispatchGroup()
dispatchGroup.enter()
DispatchQueue.global().async {
    self.asyncFunction() { error in
        if let error = error {
           debugPrint(error.alertText)
        }

        dispatchGroup.leave()
    }
}
dispatchGroup.wait()

What am I doing wrong?

By the way, I can't use notify() in this case. I don't want my function to have a completion handler.

ataravati
  • 8,891
  • 9
  • 57
  • 89
  • What thread is this code being called on? The main thread or some background thread? What thread does `asyncFunction` call its completion handler on? Is the completion handler actually called at all? – rmaddy Oct 05 '19 at 20:56
  • Then why are you using DispatchGroup if you don’t need a completion handler for the entire group? DispatchGroup is useful when you need to determine when a group of async calls are completed. If you are calling another function inside each async call, just do that; but, without the DispatchGroup – impression7vx Oct 05 '19 at 20:58
  • 3
    Really what you are doing wrong is that you are trying to turn an asynchronous operation into a synchronous one. Assuming that this code is running in the main queue, you are going to block the main queue with that `wait`. You could dispatch the whole thing asynchronously onto another queue, but at some point your are probably going to want to update the UI which means you have to dispatch back onto the main queue. Short answer: you can't perform synchronous operations in the main queue, so you should probably just refactor to pass a completion handler and handle the fact that the op is async – Paulw11 Oct 05 '19 at 20:59
  • @maddy Yes, the completion handler of `asyncFunction` is called. It's on the main thread. – ataravati Oct 05 '19 at 21:13
  • @impression7vx I'm using a `DispatchGroup`, because I need to wait until the `asyncFunction` is called before leaving the parent function. – ataravati Oct 05 '19 at 21:14
  • @Paulw11 I was trying to avoid that. This parent function is called from within a while loop. I will have to refactor a lot of code if I want to use the async function with a completion handler. And, the async function doesn't do anything complicated. The completion handler is called in less than a second. – ataravati Oct 05 '19 at 21:17
  • 1
    @ataravati Assuming the code you posted is initially called on the main queue, calling the completion handler on the main queue (why?) is your problem. The call to `wait` is blocking the main queue so the completion handler can never be called. Don't call the completion handler on the main queue. And as others have said, you shouldn't be doing any of this anyway. – rmaddy Oct 05 '19 at 21:35
  • 1
    So if you have a `while` loop, that is probably where you need the dispatch group. The you can use a `notify` on your dispatch group when all of the operations are complete. – Paulw11 Oct 05 '19 at 21:49
  • Ok, thank you all! I’ll move the `DispatchGroup` outside of the function. – ataravati Oct 05 '19 at 23:16

0 Answers0