[英]How to get the name of a coroutine in Kotlin?
I'm curious about the internal working of a coroutine when suspended
on the main thread.我很好奇协程在主线程上suspended
时的内部工作。 The real question is how to log a suspended
function which is a coroutine on the main thread.真正的问题是如何在主线程上记录作为协程的suspended
函数。 Where exactly the execution is taking place?执行究竟发生在哪里? Is it a virtual thread?是虚拟线程吗?
If you are talking about logging the coroutine name:如果您正在谈论记录协程名称:
You can achieve this by你可以通过
Give name to coroutine(if you want custom name): launch(CoroutineName("My-Coroutine"))
给协程命名(如果你想要自定义名称): launch(CoroutineName("My-Coroutine"))
Enable the logging in IntelliJ toolbar menu: Run -> Edit Configuration and add在 IntelliJ 工具栏菜单中启用日志记录:运行 -> 编辑配置并添加
-Dkotlinx.coroutines.debug
in VM options. -Dkotlinx.coroutines.debug
在 VM 选项中。
Then you can see @My-Coroutine
in logcat.然后就可以在logcat中看到@My-Coroutine
了。
Try below code after Edit Configuration change:在编辑配置更改后尝试以下代码:
fun main() = runBlocking {
println(" 'runBlocking': I'm working in thread ${Thread.currentThread().name}")
val job = launch(CoroutineName("my-custom-name")) {
println(" 'runBlocking': I'm working in thread ${Thread.currentThread().name}")
}
job.join()}
The other answers don't answer the question directly " How to get the name of a coroutine in Kotlin? ";其他答案没有直接回答问题“如何在 Kotlin 中获取协程的名称? ”; instead, they suggest how to name a coroutine.相反,他们建议如何命名协程。
If inside a coroutine, the name can be retrieved using currentCoroutineContext()[CoroutineName]
.如果在协程内部,可以使用currentCoroutineContext()[CoroutineName]
检索名称。
If outside a coroutine, there's no direct way to retrieve the name using a reference to a Job
or Deferred
(too bad).如果在协程之外,则没有直接的方法来使用对Job
或Deferred
的引用来检索名称(太糟糕了)。 However, there's a reflection hack that can be used.但是,有一个可以使用的反射技巧。 Of course, the usual warnings come attached, which are, no type safety and hacking into internal APIs that may change anytime.当然,通常会附带警告,即没有类型安全性和侵入可能随时更改的内部 API。
@Suppress("UNCHECKED_CAST")
val nameString = AbstractCoroutine::class.memberFunctions
.single { it.name == "nameString" } as Function1<AbstractCoroutine<*>, String>
val name = nameString(job as AbstractCoroutine<*>)
.replace("\"", "")
.takeWhile { it != '#' }
The method/function containing this code has to be marked with @InternalCoroutinesApi
.包含此代码的方法/函数必须用@InternalCoroutinesApi
标记。
You can give name to coroutine using CoroutineName(name:String)
method at the time of creating coroutine:您可以在创建协程时使用CoroutineName(name:String)
方法为协程CoroutineName(name:String)
:
repeat(5) {
GlobalScope.launch(CoroutineName("$it")) {
displayGreetingsFor(it)
}
}
To retrive the name given to coroutine use coroutineContext[CoroutineName.Key]
as shown below:要检索赋予协程的名称,请使用coroutineContext[CoroutineName.Key]
,如下所示:
private suspend fun displayGreetingsFor(i: Int) {
delay(100)
println(
" ${coroutineContext[CoroutineName.Key]} is executing on thread : ${Thread.currentThread().name}"
)
}
This is will print following o/p on console:这将在控制台上打印以下 o/p:
CoroutineName(0) is executing on thread : DefaultDispatcher-worker-3
CoroutineName(1) is executing on thread : DefaultDispatcher-worker-2
CoroutineName(2) is executing on thread : DefaultDispatcher-worker-8
CoroutineName(3) is executing on thread : DefaultDispatcher-worker-6
CoroutineName(4) is executing on thread : DefaultDispatcher-worker-5
Here is a sample from docs and i guess this is closest you can get. 以下是来自docs的示例,我猜这是最接近你可以得到的。
import kotlinx.coroutines.*
fun main() = runBlocking<Unit> {
launch { // context of the parent, main runBlocking coroutine
println("main runBlocking : I'm working in thread ${Thread.currentThread().name}")
}
launch(Dispatchers.Unconfined) { // not confined -- will work with main thread
println("Unconfined : I'm working in thread ${Thread.currentThread().name}")
}
launch(Dispatchers.Default) { // will get dispatched to DefaultDispatcher
println("Default : I'm working in thread ${Thread.currentThread().name}")
}
launch(newSingleThreadContext("MyOwnThread")) { // will get its own new thread
println("newSingleThreadContext: I'm working in thread ${Thread.currentThread().name}")
}
}
will print this. 会印这个。
Unconfined : I'm working in thread main
Default : I'm working in thread DefaultDispatcher-worker-1
newSingleThreadContext: I'm working in thread MyOwnThread
main runBlocking : I'm working in thread main
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.