- Learning Concurrency in Kotlin
- Miguel Angel Castiblanco Torres
- 511字
- 2021-08-05 10:46:47
Starting a coroutine with async
When a coroutine is started with the intention of processing its result, async() must be used. It will return a Deferred<T>, where Deferred is a non-blocking cancellable future – provided by the coroutines' framework – and T is the type of the result.
When using async, you must not forget to process its result – which can easily happen, so be wary.
Consider the following code:
fun main(args: Array<String>) = runBlocking {
val task = async {
doSomething()
}
task.join()
println("Completed")
}
Here, doSomething() is simply throwing an exception:
fun doSomething() {
throw UnsupportedOperationException("Can't do")
}
You may be tempted to assume that this will stop the execution of the application, the stack of the exception will be printed, and the app's exit code will be different from zero – zero means that no error happened, anything different means error. Let's see what happens when this is executed:

As you can see, there is no exception stack trace being printed in logs, the application didn't crash, and the exit code indicates successful execution.
This is because any exception happening inside an async() block will be attached to its result, and only by checking there you will find the exception. For this, the isCancelled and getCancellationException() methods can be used together to safely retrieve the exception. The previous example can be updated so that it validates the exception, like shown here:
fun main(args: Array<String>) = runBlocking {
val task = async {
doSomething()
}
task.join()
if (task.isCancelled) {
val exception = task.getCancellationException()
println("Error with message: ${exception.message}")
} else {
println("Success")
}
}
This will then print the following error:

In order to propagate the exception, await() can be called on Deferred, for example:
fun main(args: Array<String>) = runBlocking {
val task = async {
doSomething()
}
task.await()
println("Completed")
}
This will crash the application:

This crash happens because by calling await(), we are unwrapping Deferred, which in this case will unwrap to the exception and propagate it.
The main difference between waiting with join() and then validating and processing any error, and calling await() directly, is that in the first option we are handling the exception without having to propagate it, whereas by just calling await() the exception will be propagated.
For this reason, the example using await() will return the code one, meaning an error during the execution, whereas waiting with join() and using isCancelled and getCancellationException() to handle the error will result in a successful code of zero.
- C#程序設計(慕課版)
- OpenCV 3和Qt5計算機視覺應用開發
- The React Workshop
- Groovy for Domain:specific Languages(Second Edition)
- 深入理解Java7:核心技術與最佳實踐
- Cassandra Data Modeling and Analysis
- Java性能權威指南(第2版)
- Visual Basic程序設計實驗指導(第4版)
- 嚴密系統設計:方法、趨勢與挑戰
- Mastering Apache Spark 2.x(Second Edition)
- Learning Unreal Engine Android Game Development
- 單片機原理及應用技術
- 大規模語言模型開發基礎與實踐
- Mapping with ArcGIS Pro
- C#程序設計基礎與實踐