如何在Kotlin中创建此协程?

时间:2019-08-01 07:25:54

标签: kotlin coroutine kotlin-coroutines

我正在尝试从此代码中打印Hello in between World 4

import kotlinx.coroutines.*
import java.util.*

fun main() = runBlocking <Unit> {

    launch { //COR-1
        var now = Date().time

        val c= timeConusmingFunct(now) //may be some IO work

        print(" World $c") //once done lets process it 
    }

    launch{ //COR-2
        print(" in between")
    }

    print("Hello ")
}

suspend fun timeConusmingFunct(now: Long): Int{
    while(Date().time-now <4000){
        //a way to block the thread
    }

    return 4
}

我的理解是,执行主线程时,它将面向COR-1并移至下一个COR-2,然后移至最终的print("Hello")。由于COR-1将花费一些时间(〜4s),并且将耗时的功能标记为“暂停”(表示将花费一些时间)。 呼叫应该已经转到COR-2。

无论如何打印:Hello World 4 in between

为什么会这样,以及如何在协程的帮助下使代码按预期Hello in between World 4工作?

1 个答案:

答案 0 :(得分:2)

您需要对自旋等待循环进行此最小更改:

while (Date().time - now < 4000) {
    yield()
}

协程中的并发是协作的,当代码明确要求时,挂起发生。通常,它透明地发生是因为您调用了一个可挂起的函数,但是在这种情况下,您必须将其添加进去,因为您不会另外调用任何可挂起的函数。

  

如果我在这段时间内要进行一些图像处理,该怎么办?它将阻塞主线程。我希望通过协同例程来处理它。

图像处理是与CPU绑定的任务,由于它不是必须固定到GUI线程的任务,因此最好将其移交给线程池。最方便的方法是编写

withContext(Dispatchers.Default) {
    processImage(img)
}

这样,您的协程,否则将在主GUI线程上运行,将暂时跳转到线程池以执行较长的任务,然后移回GUI线程继续。在线程池上运行时,GUI线程将能够提供其他GUI事件并保持您的UI处于活动状态。