如何在Kotlin中获得协程的名称?

时间:2019-01-23 03:54:57

标签: android kotlin coroutine

我对suspended在主线程上时协程的内部工作感到好奇。真正的问题是如何在主线程上记录suspended函数,它是一个协程。究竟在哪里执行死刑?是虚拟线程吗?

4 个答案:

答案 0 :(得分:2)

如果您正在谈论记录协程名称:

您可以通过

实现
  1. 为协程命名(如果需要自定义名称):launch(CoroutineName("My-Coroutine"))

  2. 在IntelliJ工具栏菜单中启用日志记录:运行->编辑配置并添加

-Dkotlinx.coroutines.debug在VM选项中。

VM Option in Edit Configuration

然后您可以在logcat中看到@My-Coroutine

在修改配置后尝试以下代码:

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()}

结果: Result

答案 1 :(得分:1)

您可以在创建协程时使用CoroutineName(name:String)方法为协程命名:

repeat(5) {
            GlobalScope.launch(CoroutineName("$it")) {
                displayGreetingsFor(it)
            }
        }

要检索为协程命名的名称,请使用coroutineContext[CoroutineName.Key],如下所示:

private suspend fun displayGreetingsFor(i: Int) {
        delay(100)
        println(
            " ${coroutineContext[CoroutineName.Key]} is executing on thread : ${Thread.currentThread().name}"
        )
    }

这将在控制台上按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

答案 2 :(得分:0)

这是文档中的示例,我想这是您可以获得的最接近的

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}")
    }    
}

将打印此内容。

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

了解更多here

答案 3 :(得分:0)

其他答案没有直接回答问题“ 如何在Kotlin中获得协程的名称?”;相反,他们建议如何命名协程。

如果在协程内部,则可以使用currentCoroutineContext()[CoroutineName]来检索名称。

如果在协程外部,则没有直接方法使用对JobDeferred的引用来检索名称(太糟糕了)。但是,可以使用反射技巧。当然,附带了通常的警告,即没有类型安全和侵入可能随时更改的内部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 != '#' }

包含此代码的方法/函数必须用@InternalCoroutinesApi标记。