繁体   English   中英

如果从协程调用非挂起函数会发生什么?

[英]What happens if a non-suspend function is called from a coroutine?

Kotlin 中协程的关键概念之一是必须从协程或另一个挂起函数调用挂起函数

但是,挂起函数可以调用任何类型的函数,挂起或正常。
这样做的后果是什么? (这不是我的真实场景,只是出于理论原因想知道)

我想在那种情况下,创建协程的唯一目的是在调用它之前更改上下文(线程),因此它不会阻塞主线程。 但是,协程的所有其他优势会丢失吗? (合作取消,结构化并发...)

如果一个挂起函数调用另一个挂起函数,则协程被挂起,直到返回结果。

从挂起函数调用常规函数将阻塞线程。 哪个线程? 好吧,这取决于您使用的 Dispatcher。 IO能够产生数百个线程。 但是Default调度程序的线程数与您的 CPU 数量相同。 这意味着虽然这不会阻塞其他协程,但会减少可用资源的数量。

意思是:不要在这个调度器上调用可能长时间阻塞的非挂起函数,就像你不阻塞你的UI线程一样。

是的,挂起函数可能会产生相同的结果,如果您在执行诸如忙循环之类的操作而没有yield()或任何其他挂起调用。

暂停功能可以在中间暂停并稍后恢复。 从挂起函数调用普通函数,您将失去暂停执行的能力。

编译挂起函数时,kotlin 编译器会在参数中添加一个延续对象作为参数。 挂起协程需要这个延续对象。 当一个挂起函数调用另一个挂起函数时,它传递的延续对象与协程相同。

如果从挂起函数调用非挂起函数,您将无法使用该函数中的协程......就是这样

但是,协程的所有其他优势会丢失吗? (合作取消,结构化并发...)

即使是不可挂起的函数也可以通过显式检查CoroutineContext.isActive标志来参与协作取消。 不过,这更像是一个理论事实。

如果函数执行阻塞 IO 操作,它将不会响应取消请求。 该操作必须自行完成。

至于结构化并发,几乎与您所关注的相反:从不可CoroutineScope函数启动子协程是 Kotlin 的最佳实践,该函数是CoroutineScope的扩展, CoroutineScope其作为接收器调用协程构建器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM