当我使用延迟时,我应该从主线程切换到默认线程还是 IO 线程

问题描述

有时我的片段范围需要等待才能执行一些视图内容在这些情况下,我将 delay(ms) 函数添加到我的范围中。但是我的范围是用 dispathers.Main 初始化的。我知道与 Thread.sleep(ms) 不同,delay(ms) 不会阻塞当前线程。我应该考虑哪个线程执行 delay 函数

val scope = Coroutinescope(dispatchers.Main)
        scope.launch {
            //do i really need to switch IO
            withContext(dispatchers.IO) {
                delay(4000)
            }
            someUIStuff()
        }
    }

解决方法

不需要切换,delay是一个suspend函数,它会挂起当前的Coroutinescope而不是正在执行的Thread。根据 delay 函数的文档,检查第一点

/**
 * Delays coroutine for a given time without blocking a thread and resumes it after a specified time.
 * This suspending function is cancellable.
 * If the [Job] of the current coroutine is cancelled or completed while this suspending function is waiting,this function
 * immediately resumes with [CancellationException].
 *
 * Note that delay can be used in [select] invocation with [onTimeout][SelectBuilder.onTimeout] clause.
 *
 * Implementation note: how exactly time is tracked is an implementation detail of [CoroutineDispatcher] in the context.
 * @param timeMillis time in milliseconds.
 */
public suspend fun delay(timeMillis: Long) {
    if (timeMillis <= 0) return // don't delay
    return suspendCancellableCoroutine sc@ { cont: CancellableContinuation<Unit> ->
        cont.context.delay.scheduleResumeAfterDelay(timeMillis,cont)
    }
}