【问题标题】:How to create a coroutine Dispatcher for the current thread?如何为当前线程创建协程 Dispatcher?
【发布时间】:2021-01-01 16:06:25
【问题描述】:

是否可以为当前线程创建Dispatcher?检查此示例代码作为我想要完成的示例:

val dispatcher = if (parallel) {
  Dispatcher.Default
} else {
  // What should I write here so I just use the current thread to run doStuff?
}

val deferredList = list.map {
  async(dispatcher) { doStuff(it) }
}

【问题讨论】:

  • 您可能确实不能。您可以使用当前的 Dispatcher,但这与当前线程不同。
  • runBlocking 是使用当前线程作为其内部调度程序的线程。

标签: multithreading kotlin kotlin-coroutines


【解决方案1】:

当你构建一个协程时,你传递了一个CoroutineContext 作为参数。如果您不传递任何内容,新的协程将使用当前的CoroutineContext(其父级上下文)构建。

您应该瞄准CoroutineContext,而不是Dispatcher

val context = if (parallel) {
    Dispatchers.Default
} else {
    coroutineContext
}

val deferredList = list.map {
    async(context) { doStuff(it) }
}

您还可以使用 Element 类型作为键分别“提取”上下文的每个 Element

工作: coroutineContext[Job]

调度员: coroutineContext[ContinuationInterceptor]

异常处理程序: coroutineContext[CoroutineExceptionHandler]

姓名: coroutineContext[CoroutineName]

【讨论】:

    【解决方案2】:

    使用Dispatchers.Unconfined,它正好用于在当前线程上运行。

    整个代码如下所示:

    val dispatcher = if (parallel) Dispatcher.Default else Dispatchers.Unconfined
    
    val deferredList = list.map {
      async(dispatcher) { doStuff(it) }
    }
    

    【讨论】:

    • 从文档中摘录:“[...] 并让协程在相应挂起函数使用的任何线程中恢复。” (重点是我的)。它从正确的线程开始,但随后可以跳转到任何线程。
    猜你喜欢
    • 2020-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多