nswjswydcq 2024-01-19 22:55 采纳率: 0%
浏览 7

kotlin withContinuationContext内部为什么把oldValue保存到UndispatchedCoroutine,而withCoroutineContext则不必这样?

/**

  • Executes a block using a given coroutine context.
  • /
    internal actual inline fun withCoroutineContext(context: CoroutineContext, countOrElement: Any?, block: () -> T): T {
    val oldValue = updateThreadContext(context, countOrElement)
    try {
      return block()
    
    } finally {
      restoreThreadContext(context, oldValue)
    
    }
    }

/**

  • Executes a block using a context of a given continuation.
  • /
    internal actual inline fun withContinuationContext(continuation: Continuation<*>, countOrElement: Any?, block: () -> T): T {
    val context = continuation.context
    val oldValue = updateThreadContext(context, countOrElement)
    val undispatchedCompletion = if (oldValue !== NO_THREAD_ELEMENTS) {
      // Only if some values were replaced we'll go to the slow path of figuring out where/how to restore them
      continuation.updateUndispatchedCompletion(context, oldValue)
    
    } else {
      null // fast path -- don't even try to find undispatchedCompletion as there's nothing to restore in the context
    
    }
    try {
      return block()
    
    } finally {
      if (undispatchedCompletion == null || undispatchedCompletion.clearThreadContext()) {
          restoreThreadContext(context, oldValue)
      }
    
    }
    }
  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2024-01-20 08:06
    关注

    【以下回答由 GPT 生成】

    根据给出的代码,可以观察到withCoroutineContextwithContinuationContext两个函数的实现有一些区别。

    首先,我们先来看withCoroutineContext函数的实现:

    internal actual inline fun withCoroutineContext(context: CoroutineContext, countOrElement: Any?, block: () -> T): T {
      val oldValue = updateThreadContext(context, countOrElement)
      try {
        return block()
      } finally {
        restoreThreadContext(context, oldValue)
      }
    }
    

    withCoroutineContext函数中,会调用updateThreadContext函数,并将当前线程的上下文进行更新。然后,在执行block之前,会保存更新前的上下文值到oldValue变量中。finally块中会调用restoreThreadContext函数来还原上下文到oldValue保存的值。

    接下来,我们来看withContinuationContext函数的实现:

    internal actual inline fun withContinuationContext(continuation: Continuation<*>, countOrElement: Any?, block: () -> T): T {
      val context = continuation.context
      val oldValue = updateThreadContext(context, countOrElement)
      val undispatchedCompletion = if (oldValue != NO_THREAD_ELEMENTS) {
        continuation.updateUndispatchedCompletion(context, oldValue)
      } else {
        null
      }
      try {
        return block()
      } finally {
        if (undispatchedCompletion == null || undispatchedCompletion.clearThreadContext()) {
          restoreThreadContext(context, oldValue)
        }
      }
    }
    

    withContinuationContext函数中,首先获取到continuation的上下文context,然后调用updateThreadContext函数对当前线程的上下文进行更新,并保存旧的上下文值到oldValue变量中。接着判断oldValue是否等于NO_THREAD_ELEMENTS,如果不等于,则调用continuation.updateUndispatchedCompletion(context, oldValue)函数来更新continuation的未调度完成属性(undispatchedCompletion)。最后,在执行block之前,会判断undispatchedCompletion是否为null或者undispatchedCompletion.clearThreadContext()返回true,如果是,则调用restoreThreadContext函数来还原上下文到oldValue保存的值。

    可以看到,在withContinuationContext函数中,除了和withCoroutineContext相同的保存和还原上下文的操作之外,还涉及到了对continuation的未调度完成属性的更新(undispatchedCompletion)。

    因此,根据以上分析,可以总结出withContinuationContextwithCoroutineContext多了一个步骤,即对continuation的未调度完成属性的更新。而这个更新操作需要保存旧的上下文值到oldValue中,并在最后根据条件是否清除当前线程的上下文。

    至于具体的原因,我们需要根据代码上下文和更多的相关信息来进行推测和理解。从给出的代码中并不能直接得出具体原因,因此需要更多的背景和细节才能给出更准确的回答。


    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
    评论

报告相同问题?

问题事件

  • 创建了问题 1月19日

悬赏问题

  • ¥15 求解O-S方程的特征值问题给出边界层布拉休斯平行流的中性曲线
  • ¥15 谁有desed数据集呀
  • ¥20 手写数字识别运行c仿真时,程序报错错误代码sim211-100
  • ¥15 关于#hadoop#的问题
  • ¥15 (标签-Python|关键词-socket)
  • ¥15 keil里为什么main.c定义的函数在it.c调用不了
  • ¥50 切换TabTip键盘的输入法
  • ¥15 可否在不同线程中调用封装数据库操作的类
  • ¥15 微带串馈天线阵列每个阵元宽度计算
  • ¥15 keil的map文件中Image component sizes各项意思