Why is dispatchGroup.notify called after only the first task has exited?

Viewed 2583

Why is dispatchGroup.notify called after only the first task has exited?

In the following code the output is as follows:

1) Did the other thing 

**2) Did all the things** 

3) Did one thing 

4) done waiting

I would expect:

1) Did the other thing 

2) Did one thing 

3) done waiting

**4) Did all the things** 

DispatchQueue.global().async {

        let dispatchGroup = DispatchGroup()

        dispatchGroup.notify(queue: DispatchQueue.main) {
            print("Did all the things")
        }


        dispatchGroup.enter()
        DispatchQueue.global().asyncAfter(deadline: .now() + 10) {
        print("Did one thing")
            dispatchGroup.leave()

        }


        dispatchGroup.enter()
        DispatchQueue.global().async {
            print("Did the other thing")
            dispatchGroup.leave()
        }

        dispatchGroup.wait()
        print("done waiting")

    }

As a side note if I perform this on the main thread it works as expected.

1 Answers

According to the very minimal Apple docs: https://developer.apple.com/documentation/dispatch/dispatchgroup

func notify(queue: DispatchQueue, work: DispatchWorkItem) Schedules a work item to be submitted to a queue when a group of previously submitted block objects have completed.

In my example above I called dispatchQueue.notify before I had submitted my blocks to the queue. By updating the code as follows, I was able to get the expected behavior.

DispatchQueue.global().async {

        let dispatchGroup = DispatchGroup()



        dispatchGroup.enter()
        DispatchQueue.global().asyncAfter(deadline: .now() + 10) {
        print("Did one thing")
            dispatchGroup.leave()

        }


        dispatchGroup.enter()
        DispatchQueue.global().async {
            print("Did the other thing")
            dispatchGroup.leave()
        }

        dispatchGroup.notify(queue: DispatchQueue.main) {
            print("Did all the things")
        }

        dispatchGroup.wait()
        print("done waiting")

    }
Related