Open In App

withContext in Kotlin Coroutines

Last Updated : 25 Apr, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Prerequisite:

It is known that async and launch are the two ways to start the coroutine. Since It is known that async is used to get the result back, & should be used only when we need the parallel execution, whereas the launch is used when we do not want to get the result back and is used for the operation such as updating of data, etc. As we know that async is the only way till now to start the coroutine and get the result back, but the problem with async arises when we do not want to make parallel network calls. It is known when async is used, one needs to use the await() function, which leads to blocking of the main thread, but here comes the concept of withContext which removes the problem of blocking the main thread.

withContext is nothing but another way of writing the async where one does not have to write await(). When withContext, is used, it runs the tasks in series instead of parallel. So one should remember that when we have a single task in the background and want to get back the result of that task, we should use withContext. Let us take an example which demonstrates the working of the withContext:

Kotlin




// two kotlin suspend functions
// Suppose we have two tasks like below
 
private suspend fun doTaskOne(): String
{
  delay(2000)
  return "One"
}
 
private suspend fun doTaskTwo(): String
{
  delay(2000)
  return "Two"
}


Let’s run the two tasks in parallel using async-await and then using withcontext and see the difference between the two.

Kotlin




// kotlin function using async
fun startLongRunningTaskInParallel()
{
  viewModelScope.launch
  {
    val resultOneDeferred = async { TaskOne() }
    val resultTwoDeferred = async { TaskTwo() }
    val combinedResult = resultOneDeferred.await() + resultTwoDeferred.await()
  }
}


Here using async, both the task run in parallel. Now let’s use the withContext and do the same task in series with withContext.

Kotlin




// kotlin function using withContext
fun startLongRunningTaskInParallel()
{
  viewModelScope.launch
  {
    val resultOne = withContext(Dispatchers.IO) { TaskOne() }
    val resultTwo = withContext(Dispatchers.IO) { TaskTwo() }
    val combinedResult = resultOne + resultTwo
  }
}


Here one can see that in withContext everything is the same, the only difference is that here we do not have to use the await() function, and tasks are executed in a serial manner. Since here multiple tasks have been taken, one should remember that async should be used with multiple tasks and withContext should be used with a single task. Now let’s take an example and try to understand withContext in detail and how it is executed.

Kotlin




// sample kotlin program for complete
// demonstration of withContext
fun testWithContext
{
  var resultOne = "GFG"
  var resultTwo = "Is Best"
  Log.i("withContext", "Before")
  resultOne = withContext(Dispatchers.IO) { function1() }
  resultTwo = withContext(Dispatchers.IO) { function2() }
  Log.i("withContext", "After")
  val resultText = resultOne + resultTwo
  Log.i("withContext", resultText)
}
 
suspend fun function1(): String
{
  delay(1000L)
  val message = "function1"
  Log.i("withContext", message)
  return message
}
 
suspend fun function2(): String
{
  delay(100L)
  val message = "function2"
  Log.i("withContext", message)
  return message
}


Log Output

function 2 executes faster than function 1 since function 2 has less delay than function 1. Since withContext is a suspend call, that is it won’t go to the next line until it finished. Since withContext is a suspend call and does not block the main thread, we can do other tasks while the IO thread is busy in executing function1 and function 2. 



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads