我正在尝试从此代码中打印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
工作?
答案 0 :(得分:2)
您需要对自旋等待循环进行此最小更改:
while (Date().time - now < 4000) {
yield()
}
协程中的并发是协作的,当代码明确要求时,挂起发生。通常,它透明地发生是因为您调用了一个可挂起的函数,但是在这种情况下,您必须将其添加进去,因为您不会另外调用任何可挂起的函数。
如果我在这段时间内要进行一些图像处理,该怎么办?它将阻塞主线程。我希望通过协同例程来处理它。
图像处理是与CPU绑定的任务,由于它不是必须固定到GUI线程的任务,因此最好将其移交给线程池。最方便的方法是编写
withContext(Dispatchers.Default) {
processImage(img)
}
这样,您的协程,否则将在主GUI线程上运行,将暂时跳转到线程池以执行较长的任务,然后移回GUI线程继续。在线程池上运行时,GUI线程将能够提供其他GUI事件并保持您的UI处于活动状态。