简体   繁体   English

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

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

One of the key concepts of coroutines in Kotlin is that a suspend function must be called from a coroutine or another suspend function . Kotlin 中协程的关键概念之一是必须从协程或另一个挂起函数调用挂起函数

However, a suspend function can call any kind of function, suspend or normal.但是,挂起函数可以调用任何类型的函数,挂起或正常。
What is the consequence of that?这样做的后果是什么? (This is not a real scenario i have, just want to know for theoretical reasons) (这不是我的真实场景,只是出于理论原因想知道)

I imagine that in that scenario the only point of creating a coroutine would be to change the context (thread) before calling it, so it doesn´t block the main thread.我想在那种情况下,创建协程的唯一目的是在调用它之前更改上下文(线程),因此它不会阻塞主线程。 However, would all the other advantages of coroutines be lost?但是,协程的所有其他优势会丢失吗? (cooperative cancellation, structured concurrency...) (合作取消,结构化并发...)

If a suspending function calls another suspending function, then the coroutine is suspended, until the result is returned.如果一个挂起函数调用另一个挂起函数,则协程被挂起,直到返回结果。

Calling a regular function from a suspending function will block the thread.从挂起函数调用常规函数将阻塞线程。 Which thread?哪个线程? Well, that depends on the Dispatcher you're using.好吧,这取决于您使用的 Dispatcher。 IO is able to spawn hundred of threads. IO能够产生数百个线程。 But the Default dispatcher has same amount of threads as your CPUs count.但是Default调度程序的线程数与您的 CPU 数量相同。 Meaning that while this won't block other coroutines, it will reduce the amount of available resources.这意味着虽然这不会阻塞其他协程,但会减少可用资源的数量。

Meaning: don't invoke non-suspending function that may block for a long period of time on this dispatcher, same as you don't block your UI thread.意思是:不要在这个调度器上调用可能长时间阻塞的非挂起函数,就像你不阻塞你的UI线程一样。

And yes, suspending function may produce the same results, if you're do something like a busy loop without yield() or any other suspend invocation in it.是的,挂起函数可能会产生相同的结果,如果您在执行诸如忙循环之类的操作而没有yield()或任何其他挂起调用。

Suspend functions can be suspended in between and resumed later.暂停功能可以在中间暂停并稍后恢复。 Calling a normal function from a suspend function you lose the ability to pause the execution.从挂起函数调用普通函数,您将失去暂停执行的能力。

when a suspend function is compiled, kotlin compiler adds a continuation object as a parameter in the arguments.编译挂起函数时,kotlin 编译器会在参数中添加一个延续对象作为参数。 This continuation object is required for suspending a the coroutine.挂起协程需要这个延续对象。 When a suspend function calls another suspend function it passes the continuation object same is true with co-routines.当一个挂起函数调用另一个挂起函数时,它传递的延续对象与协程相同。

if a non-suspend function is called from suspend function you just wont be able to use co-routines from that function... that's it如果从挂起函数调用非挂起函数,您将无法使用该函数中的协程......就是这样

However, would all the other advantages of coroutines be lost?但是,协程的所有其他优势会丢失吗? (cooperative cancellation, structured concurrency...) (合作取消,结构化并发...)

Even a non-suspendable function can participate in cooperative cancellation by explicitly checking the CoroutineContext.isActive flag.即使是不可挂起的函数也可以通过显式检查CoroutineContext.isActive标志来参与协作取消。 This is more of a theoretical fact, though.不过,这更像是一个理论事实。

If a function performs a blocking IO operation, it will not respond to cancellation requests.如果函数执行阻塞 IO 操作,它将不会响应取消请求。 The operation will have to complete on its own.该操作必须自行完成。

As for structured concurrency, almost the opposite of your concern is true: it is a Kotlin best practice to launch child coroutines from a non-suspendable function that is instead an extension on CoroutineScope and calls the coroutine builders with it as the receiver.至于结构化并发,几乎与您所关注的相反:从不可CoroutineScope函数启动子协程是 Kotlin 的最佳实践,该函数是CoroutineScope的扩展, CoroutineScope其作为接收器调用协程构建器。

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

相关问题 如何在非挂起状态下从 DataStore 返回值 function - How to return value from DataStore in non-suspend function 挂起函数“callGetApi”只能从协程或另一个挂起函数中调用 - Suspend function 'callGetApi' should be called only from a coroutine or another suspend function 从活动中调用协程 function 返回`应该只从协程或另一个挂起函数调用` - calling coroutine function from activity returns `should be called only from a coroutine or another suspend function` 不适当的阻塞方法调用,但挂起函数“withContext”只能从协程或另一个挂起函数中调用 - Inappropriate blocking method call, but Suspend function 'withContext' should be called only from a coroutine or another suspend function 从使用 Kotlin 协程调用挂起函数的普通函数返回值 - Returning value from normal function which called suspend function using Kotlin Coroutine 协程中的非挂起函数是否仍然在另一个线程上运行? - Does a non suspend function inside a coroutine still run on another thread? Kotlin 协程中挂起函数的问题 - Problem with suspend function in Kotlin coroutine 协程挂起函数和阻塞调用 - Coroutine suspend function and blocking calls Non suspend function suspend function后不执行 - Non suspend function is not executed after suspend function 使用协程时出现挂起函数错误 - getting error of suspend function while using coroutine
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM