Dispatch Group
Dispatch group is used when we want to execute a bunch of tasks asynchronously and monitor the execution completion when all the tasks added to the group are completed.
Dispatch Group can be created like below:
let group = DispatchGroup()
There are times when we come across a situation in the project, where we need to execute multiple tasks asynchronously and perform some action when all the tasks have executed successfully.
There are multiple ways to solve any given problem. Let us consider one of the solution.
First of all, let us simulate the different tasks in a Network Manager which will take any random seconds in the range 1 to 4 seconds to complete the task. This is as shown below:
In the above Network Manager class, we have three functions.
To simulate the task function delay, we have an array [1,2,3,4].
In each function, we get the random element in this array and wait here in this method for this many seconds by using sleep method before calling the completion.
We can call these tasks in the View Controller as shown below:
In the above View Controller class, we have a method performTasksAsynchronously()
which will execute all the three tasks.
Once the tasks are executed and the completion is returned, we print that the respective task is finished.
The results in the console are as shown below:
In the above API calls, we could see that the API are executed in an asynchronous manner. We have achieved one part of the given solution to execute the tasks(in our case, multiple API calls) asynchronously.
But there is something missing in the above execution. We don’t get to know when all the API calls are finished.
Dispatch Group to the rescue
As we have discussed above, Dispatch group is used to aggregate a group of tasks and monitor the execution as a single unit.
Dispatch group provides some important methods like:
enter():
Which indicates the block has entered the groupleave()
: Which indicates the block has left the groupwait()
: Waits synchronously for the previously submitted block to finish. Additionally, wait function will take atimeout
parameter to wait synchronously for that many duration.notify(queue:)
: Perform the specified task on the specified queue when all the tasks in the group have finished executing.
For more information on this, please refer to the Apple Documentation: https://developer.apple.com/documentation/dispatch/dispatchgroup
Now with the understanding of the above methods, let us use the Dispatch Group to solve the give problem.
Let us use the Dispatch Group in the View Controller class as shown below
In the above image, we are calling the tasks using Dispatch Group.
- First we create the Dispatch Group as described above.
- Before calling each API methods, we have a
group.enter()
method which tells the group that the block has entered the group. - Once we get the completion from the respective API call methods, we call
group.leave()
which specifies that the block has finished executing. - Finally, we add a
group.notify()
after calling all the API calls. This will execute the specified block on the specified queue. Here this will printAll the tasks are executed successfully
on themain
queue.
The results in the console will look like below:
We can observe that the API are executed successfully in an asynchronous manner where task2
executed first taking 4 secs, then task3
is finished taking 3 secs and finally task1
finished taking 4 secs.
After all the tasks are executed successfully, notify
method is called to mention that the all the tasks are executed successfully.
If you have missed my other blogs on multithreading, please have a look at those below: