1, Foreword
In the previous example, we know that we can start a co process through launch or async and control its life cycle. We also know that async can run in parallel. Other operations are recorded here
2, Delayed start process
A collaborative process can be defined in advance and then started when a certain condition is triggered, as follows:
private suspend fun doSomethingUsefulOne(): Int { delay(1000L) // pretend we are doing something useful here return 13 } private suspend fun doSomethingUsefulTwo(): Int { delay(1000L) // pretend we are doing something useful here, too return 29 } @Test fun lazy(){ runBlocking { val time = measureTimeMillis { val one = async(start = CoroutineStart.LAZY) { doSomethingUsefulOne() } val two = async(start = CoroutineStart.LAZY) { doSomethingUsefulTwo() } // some computation one.start() // start the first one two.start() // start the second one println("The answer is ${one.await() + two.await()}") } println("Completed in $time ms") } }
For delayed start functions, you can use job Start() or deffered await() to start, but in this case, first use job Start() starts and then uses deffered await() to get the result, because this will not lead to a parallel program, because await() becomes a serial program
3, Globalscope async
In fact, the official does not recommend directly using GlobalScope to start the collaboration process, because it is difficult to control. For example, we write an asynchronous task (asynchronous tasks are usually named with "... Async").
- GlobalScope Is a subtle API, which may backfire in an extraordinary way. One of these ways will be explained below, so you must explicitly choose to use @ opt in (delectoroutinesapi:: class).
// The result type of somethingUsefulOneAsync is Deferred<Int> @OptIn(DelicateCoroutinesApi::class) fun somethingUsefulOneAsync() = GlobalScope.async { doSomethingUsefulOne() } // The result type of somethingUsefulTwoAsync is Deferred<Int> @OptIn(DelicateCoroutinesApi::class) fun somethingUsefulTwoAsync() = GlobalScope.async { doSomethingUsefulTwo() }
Through globalscope Async started code can perform asynchronous operations anywhere, as follows
// The result type of somethingUsefulOneAsync is Deferred<Int> @OptIn(DelicateCoroutinesApi::class) fun somethingUsefulOneAsync() = GlobalScope.async { doSomethingUsefulOne() } // The result type of somethingUsefulTwoAsync is Deferred<Int> @OptIn(DelicateCoroutinesApi::class) fun somethingUsefulTwoAsync() = GlobalScope.async { doSomethingUsefulTwo() } @Test fun taskAsync(){ runBlocking { // note that we don't have `runBlocking` to the right of `main` in this example val time = measureTimeMillis { // we can initiate async actions outside of a coroutine val one = somethingUsefulOneAsync() val two = somethingUsefulTwoAsync() // but waiting for a result must involve either suspending or blocking. // here we use `runBlocking { ... }` to block the main thread while waiting for the result runBlocking { println("The answer is ${one.await() + two.await()}") } } println("Completed in $time ms") } }
There is no problem with the code itself. If the collaboration needs to be cancelled for some reason, such as an exception, in Val one = something usefuloneasync() and one If an error occurs in await (), somethingUsefulOneAsync() will run silently in the background even if cancel() is explicitly called. Here, you can use coroutine scope to solve this problem. Therefore, the following methods need to be modified
suspend fun concurrentSum(): Int = coroutineScope { val one = async { doSomethingUsefulOne() } val two = async { doSomethingUsefulTwo() } one.await() + two.await() }
@Test fun taskAsync(){ runBlocking { val time = measureTimeMillis { println("The answer is ${concurrentSum()}") } println("Completed in $time ms") } }
This is because the coroutineScope function is a suspended function. Where it is called, it needs to be bound to the scope using it. Therefore, when the scope is cancelled, the content of this function is also cancelled.
4, Reference link
-
Write pending function
https://kotlinlang.org/docs/composing-suspending-functions.html#lazily-started-async