battle programmers alliance
Would you like to react to this message? Create an account in a few clicks or log in to continue.


battle programming a forum for elite programmers with extreme will power to sharpen their skills
 
HomeGallerySearchRegisterLog in
 

 kotling coroutines grimoire

Go down 
AuthorMessage
Moti Barski
super
super
Moti Barski

Posts : 511
Join date : 2011-08-02

kotling coroutines grimoire Empty
PostSubject: kotling coroutines grimoire   kotling coroutines grimoire EmptyTue Dec 15, 2020 6:23 pm

android studio 4.1
coroutines are the same as threads, exept better (speed & stability wise)

in the gradle file add
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2"
in dependencies {}

this grimoire will start with 2 of the best code snippets for utilizing the
coroutine jutsu.
as a reminder, to run the main func, just paste it into a kt file, it
should have a run arrow next to the function.

mulan szechuan sauce to make codes faster and taste better:
launch jutsu. this codes runs multi functions in parallal

Code:
fun main()= runBlocking{

    var c1:Int=1;
    var test = ""
    var test2:String = "null"
    launch (Dispatchers.Default){ while (c1<5){
        c1++;
        val deferred1 = async { tic("tick") }
        val deferred2 = async { tic("tok") }
        test = async { tic("tek") }.await()
        test2 = "test ok"
    } }.join()
//.join can be omitted for extra speed
    println(test)
    println("test result : $test2")
    println("main thread end")
}
suspend fun tic(startNum: String):String{
    delay(1000)
    println(startNum)
    return  "test ok"
}

alter code :

Code:
fun main()= runBlocking{

    var c1:Int=1;
    var test = ""
    var test2:String = "null"
    launch (Dispatchers.Default){ while (c1<5){
        c1++;
        val deferred1 = async { tic("tick") }
        val deferred2 = async { tic("tok") }
        test = async { tic("tek") }.await()
        test2 = "test ok"
    } }.invokeOnCompletion { throwable -> println("done") }
//.join can be omitted for extra speed
    println(test)
    println("test result : $test2")
    println("main thread end")
}
suspend fun tic(startNum: String):String{
    delay(1000)
    println(startNum)
    return  "test ok"
}

###################################
kotlin android studio handler tick event alternative simpler stronger code :

Code:
fun main()= runBlocking{

    var c1:Int=1;
    launch (Dispatchers.Default){ while (c1<10){
        c1++;
        val deferred1 = async { tic("tick") }
        val deferred2 = async { tic("tok") }.await()
    } }
    println("main thread end")
}
suspend fun tic(startNum: String){
    delay(1000)
    println(startNum)
}

output :

main thread end
tick
tok
tick
tok
tok
tick
tok
tick
tick
tok
tok
tick
tick
tok
tick
tok
tok
tick

Process finished with exit code 0
##################################################

_________________
MB over and out emp it up
Back to top Go down
Moti Barski
super
super
Moti Barski

Posts : 511
Join date : 2011-08-02

kotling coroutines grimoire Empty
PostSubject: Re: kotling coroutines grimoire   kotling coroutines grimoire EmptyTue Dec 15, 2020 6:30 pm

Code:
Java:
fun main(){
    println("main starts")
    routin(1,500)
    print("main ends")
}
fun routin(number: Int, delay: Long){
    println("routin $number starts work")
    Thread.sleep(delay)
    println("routin $number has finished")
}

click ▶ to run)
this runs and pauses on the main thread
####################################################

Code:
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking

fun main(){
    exampleBlocking()
}

fun exampleBlocking() {
    println("one")
    //block thread and summon a coroutin :
    runBlocking { printlnDelayed("two") }
    println("three")
}

suspend fun printlnDelayed(message: String) {
    //this is a coroutin
    // Complex calculation
    delay(1000)
    println(message)
}
shorter write :
Code:
fun main(){
    exampleBlocking()
}

fun exampleBlocking() = runBlocking{
    println("one")
    //block thread and summon a coroutin :
    printlnDelayed("two")
    println("three")
}

suspend fun printlnDelayed(message: String) {
    //this is a coroutin
    // Complex calculation
    delay(1000)
    println(message)
}

#############################################
Code:
fun main(){
    exampleBlockingDispatcher()
}
fun exampleBlockingDispatcher(){
    runBlocking(Dispatchers.Default) {
        println("one - from thread ${Thread.currentThread().name}")
        printlnDelayed("two - from thread ${Thread.currentThread().name}")
    }
    // Outside of runBlocking to show that it's running in the blocked main thread
    println("three - from thread ${Thread.currentThread().name}")
    // It still runs only after the runBlocking is fully executed.
}
suspend fun printlnDelayed(message: String) {
    //this is a coroutin
    // Complex calculation
    delay(1000)
    println(message)
}
a dispacher mostly switches the runblocking to a different thread
output :
one - from thread DefaultDispatcher-worker-1
two - from thread DefaultDispatcher-worker-1
three - from thread main

####################################################

_________________
MB over and out emp it up
Back to top Go down
Moti Barski
super
super
Moti Barski

Posts : 511
Join date : 2011-08-02

kotling coroutines grimoire Empty
PostSubject: Re: kotling coroutines grimoire   kotling coroutines grimoire EmptyTue Dec 15, 2020 6:35 pm

global dispacher : this will run on a separate thread without blocking the
summoner thread :

Code:
fun main(){
    exampleLaunchGlobal()
}

fun exampleLaunchGlobalWaiting() = runBlocking {
    println("one - from thread ${Thread.currentThread().name}")
 
    val job = GlobalScope.launch {
        printlnDelayed("two - from thread ${Thread.currentThread().name}")
    }
 
    println("three - from thread ${Thread.currentThread().name}")
    job.join()
}
suspend fun printlnDelayed(message: String) {
    //this is a coroutin
    // Complex calculation
    delay(1000)
    println(message)
}

################################
coroutin on a launch scope :

fun exampleLaunchCoroutineScope() = runBlocking {
println("one - from thread ${Thread.currentThread().name}")
launch {
printlnDelayed("two - from thread ${Thread.currentThread().name}")
}
println("three - from thread ${Thread.currentThread().name}")
}

those will all run on the same thread
to change the thread of the dispacher :

Code:
fun exampleLaunchCoroutineScope() = runBlocking {
    println("one - from thread ${Thread.currentThread().name}")
    launch(Dispatchers.Default) {
        printlnDelayed("two - from thread ${Thread.currentThread().name}")
    }
    println("three - from thread ${Thread.currentThread().name}")
}

also not to access the views like text views on android, this can oly be done via the
main thread or Dispacher.main

using your own custom dispacher :


Code:
fun exampleLaunchCoroutineScope() = runBlocking {
    println("one - from thread ${Thread.currentThread().name}")
    val customDispatcher = Executors.newFixedThreadPool(2).asCoroutineDispatcher()
    launch(customDispatcher) {
        printlnDelayed("two - from thread ${Thread.currentThread().name}")
    }
    println("three - from thread ${Thread.currentThread().name}")
}

####################################
async with value get set:

Code:
suspend fun calculateHardThings(startNum: Int): Int {
    delay(1000)
    return startNum * 10
}
fun exampleAsyncAwait() = runBlocking {
    val startTime = System.currentTimeMillis()

    val deferred1 = async { calculateHardThings(10) }
    val deferred2 = async { calculateHardThings(20) }
    val deferred3 = async { calculateHardThings(30) }

    val sum = deferred1.await() + deferred2.await() + deferred3.await()
    println("async/await result = $sum")

    val endTime = System.currentTimeMillis()
    println("Time taken: ${endTime - startTime}")
}

you can also use await like this :
val deferred1 = async { calculateHardThings(10) }.await()
#############################################################
kotlin coroutins async timer

Code:
suspend fun calculateHardThings(startNum: String){
    delay(1000)
    println(startNum)
}
fun exampleAsyncAwait() = runBlocking {
    val startTime = System.currentTimeMillis()
    var c1:Int=1;
    while (c1<10){
        c1++;
        val deferred1 = async { calculateHardThings("tick") }
        val deferred2 = async { calculateHardThings("tok") }.await()
    }

    println("end")
}

###############################################################
if you want to run things async but not block the thread and with context:
which is the same as calling await after each async.
this is best used for heavy calculations so as to not burden the main or UI thread

Code:
suspend fun calculateHardThings(startNum: Int): Int {
    delay(1000)
    return startNum * 10
}
fun exampleWithContext() = runBlocking {
    val startTime = System.currentTimeMillis()

    val result1 = withContext(Dispatchers.Default) { calculateHardThings(10) }
    val result2 = withContext(Dispatchers.Default) { calculateHardThings(20) }
    val result3 = withContext(Dispatchers.Default) { calculateHardThings(30) }

    val sum = result1 + result2 + result3
    println("async/await result = $sum")

    val endTime = System.currentTimeMillis()
    println("Time taken: ${endTime - startTime}")
}

###################################
timer on BG thread :

Code:
fun main(){
    exampleAsyncAwait()
    println("main thread end")
}
suspend fun calculateHardThings(startNum: String){
    delay(1000)
    println(startNum)
}
fun exampleAsyncAwait() = runBlocking {
    val startTime = System.currentTimeMillis()
    var c1:Int=1;
    launch { while (c1<10){
        c1++;
        val deferred1 = async { calculateHardThings("tick") }
        val deferred2 = async { calculateHardThings("tok") }.await()
    } }

    println("end")//main code thread, does not wait for the timer which is in the BackGround
}

_________________
MB over and out emp it up
Back to top Go down
Moti Barski
super
super
Moti Barski

Posts : 511
Join date : 2011-08-02

kotling coroutines grimoire Empty
PostSubject: Re: kotling coroutines grimoire   kotling coroutines grimoire EmptyTue Dec 15, 2020 6:39 pm

#################

Code:
fun main()= runBlocking{

    repeat(1_000){
        launch { delay(1000)
        print("creamed corn")}
    }
}

unlike threads you can summon a million coroutins and it runs very fast
Code:
fun main()= runBlocking<Unit>{
//official write style
    repeat(1_000){
        launch { delay(1000)
        print("creamed corn")}
    }
}
#####################################
Code:
fun main()= runBlocking<Unit>{
//official write style
        val job = launch { delay(1000)
        print("creamed corn")}
    job.join()//run once
}

Code:
fun main()= runBlocking<Unit>{
//official write style
        val job = launch(start = CoroutineStart.LAZY) { delay(1000)
        print("creamed corn")}
    delay(200)
    job.start()//start launch with delay
}

####################################################

timeout job cancelation :

Code:
fun main()= runBlocking<Unit>{
//official write style
        val job = GlobalScope.launch { print("creamed corn")
        withTimeout(3000){
            //if this code doesn't finish in timeout time it is canceled
            delay(500)
            print("creamed corn")
            delay(3000)
            print("finished")// doesn't print
        }
        }
}

manual launch job cancelation :

Code:
fun main()= runBlocking<Unit>{
//official write style
        val job = launch {
        withTimeout(3000){
            println("test")    ;this.cancel();      delay(10)

            println("you can not see me in the output window")
        }
        }
}

##############################
measure function run time

Code:
@ExperimentalTime
fun main()= runBlocking<Unit>{
//official write style

    launch {
        val duration = measureTime { calculateHardThings(1000) }
        println(duration)
    }
}

###############################
setting coroutine context to default so as to not jam the UI :

Code:
@ExperimentalTime
fun main()= runBlocking<Unit>{
//official write style

    launch (context = Dispatchers.Default){
        val duration = measureTime { calculateHardThings(1000) }
        println(duration)
    }
}

###############################3
access cancellation event for coroutine :

Code:
val scope= CoroutineScope(Dispatchers.Default)
fun main ()= runBlocking {
    val job = scope.launch {
        delay(100)
        println("coroutine completed")
    }
    job.invokeOnCompletion { throwable ->  if(throwable is CancellationException){println("the coroutine has been cancelled")} }
    delay(50)
    onDestroy()
}

fun onDestroy(){
    println("lifecycle end")
    scope.cancel()
}

#############################

would you like to know more ?
https://www.geeksforgeeks.org/scopes-in-kotlin-coroutines/

####################################
cancelling a coroutine with a default dispacher :

Code:
fun main()= runBlocking{
    val job = launch(Dispatchers.Default){
        repeat(10){index ->
            ensureActive()
            println("operation: $index")
            Thread.sleep(100)
        }
    }
    delay(250)
    println("cancelling coroutin")
    job.cancel()
}

ensuring no cancelling on cancelled coroutins clean up code block :
Code:
fun main()= runBlocking{
    val job = launch(Dispatchers.Default){
        repeat(10){index ->
            if(isActive){println("operation: $index");Thread.sleep(100)}
            else{
                withContext(NonCancellable){
                    delay(100)
                    println("clean up")
                    throw CancellationException()
                }}
        }
    }
    delay(250)
    println("cancelling coroutin")
    job.cancel()
}

rain

_________________
MB over and out emp it up
Back to top Go down
kurosen
codding
codding
kurosen

Posts : 292
Join date : 2012-04-17

kotling coroutines grimoire Empty
PostSubject: Re: kotling coroutines grimoire   kotling coroutines grimoire EmptyTue Dec 15, 2020 7:23 pm

volatile var :

Code:
import android.arch.lifecycle.ViewModel
import android.support.annotation.RestrictTo
import kotlinx.coroutines.*
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import kotlin.time.ExperimentalTime
import kotlin.time.measureTime
@Volatile var fudge = "fudge" //wherever this var is accessed from it will retrieve or save the latest value
fun main()= runBlocking{
    val job = launch(Dispatchers.Default){
        var finished :Boolean = false;
        repeat(10000){index ->
            if(!finished){
            delay(10)
            if (fudge.equals(" morphed")){println(index);finished=true}
        }}
    }
    delay(200)
    fudge = " morphed"
    print(fudge)
}
Back to top Go down
 
kotling coroutines grimoire
Back to top 
Page 1 of 1

Permissions in this forum:You cannot reply to topics in this forum
battle programmers alliance :: battle programming alliance :: battle programming-
Jump to: